// SPDX-License-Identifier: GPL-2.0
/*
 * Clock driver for TPS68470 PMIC
 *
 * Copyright (c) 2021 Red Hat Inc.
 * Copyright (C) 2018 Intel Corporation
 *
 * Authors:
 *	Hans de Goede <hdegoede@redhat.com>
 *	Zaikuo Wang <zaikuo.wang@intel.com>
 *	Tianshu Qiu <tian.shu.qiu@intel.com>
 *	Jian Xu Zheng <jian.xu.zheng@intel.com>
 *	Yuning Pu <yuning.pu@intel.com>
 *	Antti Laakso <antti.laakso@intel.com>
 */

#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/kernel.h>
#include <linux/mfd/tps68470.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/platform_data/tps68470.h>
#include <linux/regmap.h>

#define TPS68470_CLK_NAME "tps68470-clk"

#define to_tps68470_clkdata(clkd) \
	container_of(clkd, struct tps68470_clkdata, clkout_hw)

static struct tps68470_clkout_freqs {
	unsigned long freq;
	unsigned int xtaldiv;
	unsigned int plldiv;
	unsigned int postdiv;
	unsigned int buckdiv;
	unsigned int boostdiv;
} clk_freqs[] = {
/*
 *  The PLL is used to multiply the crystal oscillator
 *  frequency range of 3 MHz to 27 MHz by a programmable
 *  factor of F = (M/N)*(1/P) such that the output
 *  available at the HCLK_A or HCLK_B pins are in the range
 *  of 4 MHz to 64 MHz in increments of 0.1 MHz.
 *
 * hclk_# = osc_in * (((plldiv*2)+320) / (xtaldiv+30)) * (1 / 2^postdiv)
 *
 * PLL_REF_CLK should be as close as possible to 100kHz
 * PLL_REF_CLK = input clk / XTALDIV[7:0] + 30)
 *
 * PLL_VCO_CLK = (PLL_REF_CLK * (plldiv*2 + 320))
 *
 * BOOST should be as close as possible to 2Mhz
 * BOOST = PLL_VCO_CLK / (BOOSTDIV[4:0] + 16) *
 *
 * BUCK should be as close as possible to 5.2Mhz
 * BUCK = PLL_VCO_CLK / (BUCKDIV[3:0] + 5)
 *
 * osc_in   xtaldiv  plldiv   postdiv   hclk_#
 * 20Mhz    170      32       1         19.2Mhz
 * 20Mhz    170      40       1         20Mhz
 * 20Mhz    170      80       1         24Mhz
 */
	{ 19200000, 170, 32, 1, 2, 3 },
	{ 20000000, 170, 40, 1, 3, 4 },
	{ 24000000, 170, 80, 1, 4, 8 },
};

struct tps68470_clkdata {
	struct clk_hw clkout_hw;
	struct regmap *regmap;
	unsigned long rate;
};

static int tps68470_clk_is_prepared(struct clk_hw *hw)
{
	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
	int val;

	if (regmap_read(clkdata->regmap, TPS68470_REG_PLLCTL, &val))
		return 0;

	return val & TPS68470_PLL_EN_MASK;
}

static int tps68470_clk_prepare(struct clk_hw *hw)
{
	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);

	regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1,
			   (TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_A_SHIFT) |
			   (TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_B_SHIFT));

	regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL,
			   TPS68470_PLL_EN_MASK, TPS68470_PLL_EN_MASK);

	/*
	 * The PLLCTL reg lock bit is set by the PMIC after approx. 4ms and
	 * does not indicate a true lock, so just wait 4 ms.
	 */
	usleep_range(4000, 5000);

	return 0;
}

static void tps68470_clk_unprepare(struct clk_hw *hw)
{
	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);

	/* Disable clock first ... */
	regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL, TPS68470_PLL_EN_MASK, 0);

	/* ... and then tri-state the clock outputs. */
	regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1, 0);
}

static unsigned long tps68470_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);

	return clkdata->rate;
}

/*
 * This returns the index of the clk_freqs[] cfg with the closest rate for
 * use in tps68470_clk_round_rate(). tps68470_clk_set_rate() checks that
 * the rate of the returned cfg is an exact match.
 */
static unsigned int tps68470_clk_cfg_lookup(unsigned long rate)
{
	long diff, best_diff = LONG_MAX;
	unsigned int i, best_idx = 0;

	for (i = 0; i < ARRAY_SIZE(clk_freqs); i++) {
		diff = clk_freqs[i].freq - rate;
		if (diff == 0)
			return i;

		diff = abs(diff);
		if (diff < best_diff) {
			best_diff = diff;
			best_idx = i;
		}
	}

	return best_idx;
}

static long tps68470_clk_round_rate(struct clk_hw *hw, unsigned long rate,
				    unsigned long *parent_rate)
{
	unsigned int idx = tps68470_clk_cfg_lookup(rate);

	return clk_freqs[idx].freq;
}

static int tps68470_clk_set_rate(struct clk_hw *hw, unsigned long rate,
				 unsigned long parent_rate)
{
	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
	unsigned int idx = tps68470_clk_cfg_lookup(rate);

	if (rate != clk_freqs[idx].freq)
		return -EINVAL;

	regmap_write(clkdata->regmap, TPS68470_REG_BOOSTDIV, clk_freqs[idx].boostdiv);
	regmap_write(clkdata->regmap, TPS68470_REG_BUCKDIV, clk_freqs[idx].buckdiv);
	regmap_write(clkdata->regmap, TPS68470_REG_PLLSWR, TPS68470_PLLSWR_DEFAULT);
	regmap_write(clkdata->regmap, TPS68470_REG_XTALDIV, clk_freqs[idx].xtaldiv);
	regmap_write(clkdata->regmap, TPS68470_REG_PLLDIV, clk_freqs[idx].plldiv);
	regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV, clk_freqs[idx].postdiv);
	regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV2, clk_freqs[idx].postdiv);
	regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG2, TPS68470_CLKCFG2_DRV_STR_2MA);

	regmap_write(clkdata->regmap, TPS68470_REG_PLLCTL,
		     TPS68470_OSC_EXT_CAP_DEFAULT << TPS68470_OSC_EXT_CAP_SHIFT |
		     TPS68470_CLK_SRC_XTAL << TPS68470_CLK_SRC_SHIFT);

	clkdata->rate = rate;

	return 0;
}

static const struct clk_ops tps68470_clk_ops = {
	.is_prepared = tps68470_clk_is_prepared,
	.prepare = tps68470_clk_prepare,
	.unprepare = tps68470_clk_unprepare,
	.recalc_rate = tps68470_clk_recalc_rate,
	.round_rate = tps68470_clk_round_rate,
	.set_rate = tps68470_clk_set_rate,
};

static int tps68470_clk_probe(struct platform_device *pdev)
{
	struct tps68470_clk_platform_data *pdata = pdev->dev.platform_data;
	struct clk_init_data tps68470_clk_initdata = {
		.name = TPS68470_CLK_NAME,
		.ops = &tps68470_clk_ops,
		/* Changing the dividers when the PLL is on is not allowed */
		.flags = CLK_SET_RATE_GATE,
	};
	struct tps68470_clkdata *tps68470_clkdata;
	int ret;

	tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata),
					GFP_KERNEL);
	if (!tps68470_clkdata)
		return -ENOMEM;

	tps68470_clkdata->regmap = dev_get_drvdata(pdev->dev.parent);
	tps68470_clkdata->clkout_hw.init = &tps68470_clk_initdata;

	/* Set initial rate */
	tps68470_clk_set_rate(&tps68470_clkdata->clkout_hw, clk_freqs[0].freq, 0);

	ret = devm_clk_hw_register(&pdev->dev, &tps68470_clkdata->clkout_hw);
	if (ret)
		return ret;

	ret = devm_clk_hw_register_clkdev(&pdev->dev, &tps68470_clkdata->clkout_hw,
					  TPS68470_CLK_NAME, NULL);
	if (ret)
		return ret;

	if (pdata) {
		ret = devm_clk_hw_register_clkdev(&pdev->dev,
						  &tps68470_clkdata->clkout_hw,
						  pdata->consumer_con_id,
						  pdata->consumer_dev_name);
	}

	return ret;
}

static struct platform_driver tps68470_clk_driver = {
	.driver = {
		.name = TPS68470_CLK_NAME,
	},
	.probe = tps68470_clk_probe,
};

/*
 * The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers
 * registering before the drivers for the camera-sensors which use them bind.
 * subsys_initcall() ensures this when the drivers are builtin.
 */
static int __init tps68470_clk_init(void)
{
	return platform_driver_register(&tps68470_clk_driver);
}
subsys_initcall(tps68470_clk_init);

static void __exit tps68470_clk_exit(void)
{
	platform_driver_unregister(&tps68470_clk_driver);
}
module_exit(tps68470_clk_exit);

MODULE_ALIAS("platform:tps68470-clk");
MODULE_DESCRIPTION("clock driver for TPS68470 pmic");
MODULE_LICENSE("GPL");
