// SPDX-License-Identifier: GPL-2.0
/*
 * StarFive JH7110 PLL Clock Generator Driver
 *
 * Copyright (C) 2023 StarFive Technology Co., Ltd.
 * Copyright (C) 2023 Emil Renner Berthing <emil.renner.berthing@canonical.com>
 *
 * This driver is about to register JH7110 PLL clock generator and support ops.
 * The JH7110 have three PLL clock, PLL0, PLL1 and PLL2.
 * Each PLL clocks work in integer mode or fraction mode by some dividers,
 * and the configuration registers and dividers are set in several syscon registers.
 * The formula for calculating frequency is:
 * Fvco = Fref * (NI + NF) / M / Q1
 * Fref: OSC source clock rate
 * NI: integer frequency dividing ratio of feedback divider, set by fbdiv[11:0].
 * NF: fractional frequency dividing ratio, set by frac[23:0]. NF = frac[23:0] / 2^24 = 0 ~ 0.999.
 * M: frequency dividing ratio of pre-divider, set by prediv[5:0].
 * Q1: frequency dividing ratio of post divider, set by 2^postdiv1[1:0], eg. 1, 2, 4 or 8.
 */

#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include <dt-bindings/clock/starfive,jh7110-crg.h>

/* this driver expects a 24MHz input frequency from the oscillator */
#define JH7110_PLL_OSC_RATE		24000000UL

#define JH7110_PLL0_PD_OFFSET		0x18
#define JH7110_PLL0_DACPD_SHIFT		24
#define JH7110_PLL0_DACPD_MASK		BIT(24)
#define JH7110_PLL0_DSMPD_SHIFT		25
#define JH7110_PLL0_DSMPD_MASK		BIT(25)
#define JH7110_PLL0_FBDIV_OFFSET	0x1c
#define JH7110_PLL0_FBDIV_SHIFT		0
#define JH7110_PLL0_FBDIV_MASK		GENMASK(11, 0)
#define JH7110_PLL0_FRAC_OFFSET		0x20
#define JH7110_PLL0_PREDIV_OFFSET	0x24

#define JH7110_PLL1_PD_OFFSET		0x24
#define JH7110_PLL1_DACPD_SHIFT		15
#define JH7110_PLL1_DACPD_MASK		BIT(15)
#define JH7110_PLL1_DSMPD_SHIFT		16
#define JH7110_PLL1_DSMPD_MASK		BIT(16)
#define JH7110_PLL1_FBDIV_OFFSET	0x24
#define JH7110_PLL1_FBDIV_SHIFT		17
#define JH7110_PLL1_FBDIV_MASK		GENMASK(28, 17)
#define JH7110_PLL1_FRAC_OFFSET		0x28
#define JH7110_PLL1_PREDIV_OFFSET	0x2c

#define JH7110_PLL2_PD_OFFSET		0x2c
#define JH7110_PLL2_DACPD_SHIFT		15
#define JH7110_PLL2_DACPD_MASK		BIT(15)
#define JH7110_PLL2_DSMPD_SHIFT		16
#define JH7110_PLL2_DSMPD_MASK		BIT(16)
#define JH7110_PLL2_FBDIV_OFFSET	0x2c
#define JH7110_PLL2_FBDIV_SHIFT		17
#define JH7110_PLL2_FBDIV_MASK		GENMASK(28, 17)
#define JH7110_PLL2_FRAC_OFFSET		0x30
#define JH7110_PLL2_PREDIV_OFFSET	0x34

#define JH7110_PLL_FRAC_SHIFT		0
#define JH7110_PLL_FRAC_MASK		GENMASK(23, 0)
#define JH7110_PLL_POSTDIV1_SHIFT	28
#define JH7110_PLL_POSTDIV1_MASK	GENMASK(29, 28)
#define JH7110_PLL_PREDIV_SHIFT		0
#define JH7110_PLL_PREDIV_MASK		GENMASK(5, 0)

enum jh7110_pll_mode {
	JH7110_PLL_MODE_FRACTION,
	JH7110_PLL_MODE_INTEGER,
};

struct jh7110_pll_preset {
	unsigned long freq;
	u32 frac;		/* frac value should be decimals multiplied by 2^24 */
	unsigned fbdiv    : 12;	/* fbdiv value should be 8 to 4095 */
	unsigned prediv   :  6;
	unsigned postdiv1 :  2;
	unsigned mode     :  1;
};

struct jh7110_pll_info {
	char *name;
	const struct jh7110_pll_preset *presets;
	unsigned int npresets;
	struct {
		unsigned int pd;
		unsigned int fbdiv;
		unsigned int frac;
		unsigned int prediv;
	} offsets;
	struct {
		u32 dacpd;
		u32 dsmpd;
		u32 fbdiv;
	} masks;
	struct {
		char dacpd;
		char dsmpd;
		char fbdiv;
	} shifts;
};

#define _JH7110_PLL(_idx, _name, _presets)				\
	[_idx] = {							\
		.name = _name,						\
		.presets = _presets,					\
		.npresets = ARRAY_SIZE(_presets),			\
		.offsets = {						\
			.pd = JH7110_PLL##_idx##_PD_OFFSET,		\
			.fbdiv = JH7110_PLL##_idx##_FBDIV_OFFSET,	\
			.frac = JH7110_PLL##_idx##_FRAC_OFFSET,		\
			.prediv = JH7110_PLL##_idx##_PREDIV_OFFSET,	\
		},							\
		.masks = {						\
			.dacpd = JH7110_PLL##_idx##_DACPD_MASK,		\
			.dsmpd = JH7110_PLL##_idx##_DSMPD_MASK,		\
			.fbdiv = JH7110_PLL##_idx##_FBDIV_MASK,		\
		},							\
		.shifts = {						\
			.dacpd = JH7110_PLL##_idx##_DACPD_SHIFT,	\
			.dsmpd = JH7110_PLL##_idx##_DSMPD_SHIFT,	\
			.fbdiv = JH7110_PLL##_idx##_FBDIV_SHIFT,	\
		},							\
	}
#define JH7110_PLL(idx, name, presets) _JH7110_PLL(idx, name, presets)

struct jh7110_pll_data {
	struct clk_hw hw;
	unsigned int idx;
};

struct jh7110_pll_priv {
	struct device *dev;
	struct regmap *regmap;
	struct jh7110_pll_data pll[JH7110_PLLCLK_END];
};

struct jh7110_pll_regvals {
	u32 dacpd;
	u32 dsmpd;
	u32 fbdiv;
	u32 frac;
	u32 postdiv1;
	u32 prediv;
};

/*
 * Because the pll frequency is relatively fixed,
 * it cannot be set arbitrarily, so it needs a specific configuration.
 * PLL0 frequency should be multiple of 125MHz (USB frequency).
 */
static const struct jh7110_pll_preset jh7110_pll0_presets[] = {
	{
		.freq = 375000000,
		.fbdiv = 125,
		.prediv = 8,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 500000000,
		.fbdiv = 125,
		.prediv = 6,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 625000000,
		.fbdiv = 625,
		.prediv = 24,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 750000000,
		.fbdiv = 125,
		.prediv = 4,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 875000000,
		.fbdiv = 875,
		.prediv = 24,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 1000000000,
		.fbdiv = 125,
		.prediv = 3,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 1250000000,
		.fbdiv = 625,
		.prediv = 12,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 1375000000,
		.fbdiv = 1375,
		.prediv = 24,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 1500000000,
		.fbdiv = 125,
		.prediv = 2,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	},
};

static const struct jh7110_pll_preset jh7110_pll1_presets[] = {
	{
		.freq = 1066000000,
		.fbdiv = 533,
		.prediv = 12,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 1200000000,
		.fbdiv = 50,
		.prediv = 1,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 1400000000,
		.fbdiv = 350,
		.prediv = 6,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 1600000000,
		.fbdiv = 200,
		.prediv = 3,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	},
};

static const struct jh7110_pll_preset jh7110_pll2_presets[] = {
	{
		.freq = 1188000000,
		.fbdiv = 99,
		.prediv = 2,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	}, {
		.freq = 1228800000,
		.fbdiv = 256,
		.prediv = 5,
		.postdiv1 = 0,
		.mode = JH7110_PLL_MODE_INTEGER,
	},
};

static const struct jh7110_pll_info jh7110_plls[JH7110_PLLCLK_END] = {
	JH7110_PLL(JH7110_PLLCLK_PLL0_OUT, "pll0_out", jh7110_pll0_presets),
	JH7110_PLL(JH7110_PLLCLK_PLL1_OUT, "pll1_out", jh7110_pll1_presets),
	JH7110_PLL(JH7110_PLLCLK_PLL2_OUT, "pll2_out", jh7110_pll2_presets),
};

static struct jh7110_pll_data *jh7110_pll_data_from(struct clk_hw *hw)
{
	return container_of(hw, struct jh7110_pll_data, hw);
}

static struct jh7110_pll_priv *jh7110_pll_priv_from(struct jh7110_pll_data *pll)
{
	return container_of(pll, struct jh7110_pll_priv, pll[pll->idx]);
}

static void jh7110_pll_regvals_get(struct regmap *regmap,
				   const struct jh7110_pll_info *info,
				   struct jh7110_pll_regvals *ret)
{
	u32 val;

	regmap_read(regmap, info->offsets.pd, &val);
	ret->dacpd = (val & info->masks.dacpd) >> info->shifts.dacpd;
	ret->dsmpd = (val & info->masks.dsmpd) >> info->shifts.dsmpd;

	regmap_read(regmap, info->offsets.fbdiv, &val);
	ret->fbdiv = (val & info->masks.fbdiv) >> info->shifts.fbdiv;

	regmap_read(regmap, info->offsets.frac, &val);
	ret->frac = (val & JH7110_PLL_FRAC_MASK) >> JH7110_PLL_FRAC_SHIFT;
	ret->postdiv1 = (val & JH7110_PLL_POSTDIV1_MASK) >> JH7110_PLL_POSTDIV1_SHIFT;

	regmap_read(regmap, info->offsets.prediv, &val);
	ret->prediv = (val & JH7110_PLL_PREDIV_MASK) >> JH7110_PLL_PREDIV_SHIFT;
}

static unsigned long jh7110_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
	struct jh7110_pll_data *pll = jh7110_pll_data_from(hw);
	struct jh7110_pll_priv *priv = jh7110_pll_priv_from(pll);
	struct jh7110_pll_regvals val;
	unsigned long rate;

	jh7110_pll_regvals_get(priv->regmap, &jh7110_plls[pll->idx], &val);

	/*
	 * dacpd = dsmpd = 0: fraction mode
	 * dacpd = dsmpd = 1: integer mode, frac value ignored
	 *
	 * rate = parent * (fbdiv + frac/2^24) / prediv / 2^postdiv1
	 *      = (parent * fbdiv + parent * frac / 2^24) / (prediv * 2^postdiv1)
	 */
	if (val.dacpd == 0 && val.dsmpd == 0)
		rate = parent_rate * val.frac / (1UL << 24);
	else if (val.dacpd == 1 && val.dsmpd == 1)
		rate = 0;
	else
		return 0;

	rate += parent_rate * val.fbdiv;
	rate /= val.prediv << val.postdiv1;

	return rate;
}

static int jh7110_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
{
	struct jh7110_pll_data *pll = jh7110_pll_data_from(hw);
	const struct jh7110_pll_info *info = &jh7110_plls[pll->idx];
	const struct jh7110_pll_preset *selected = &info->presets[0];
	unsigned int idx;

	/* if the parent rate doesn't match our expectations the presets won't work */
	if (req->best_parent_rate != JH7110_PLL_OSC_RATE) {
		req->rate = jh7110_pll_recalc_rate(hw, req->best_parent_rate);
		return 0;
	}

	/* find highest rate lower or equal to the requested rate */
	for (idx = 1; idx < info->npresets; idx++) {
		const struct jh7110_pll_preset *val = &info->presets[idx];

		if (req->rate < val->freq)
			break;

		selected = val;
	}

	req->rate = selected->freq;
	return 0;
}

static int jh7110_pll_set_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long parent_rate)
{
	struct jh7110_pll_data *pll = jh7110_pll_data_from(hw);
	struct jh7110_pll_priv *priv = jh7110_pll_priv_from(pll);
	const struct jh7110_pll_info *info = &jh7110_plls[pll->idx];
	const struct jh7110_pll_preset *val;
	unsigned int idx;

	/* if the parent rate doesn't match our expectations the presets won't work */
	if (parent_rate != JH7110_PLL_OSC_RATE)
		return -EINVAL;

	for (idx = 0, val = &info->presets[0]; idx < info->npresets; idx++, val++) {
		if (val->freq == rate)
			goto found;
	}
	return -EINVAL;

found:
	if (val->mode == JH7110_PLL_MODE_FRACTION)
		regmap_update_bits(priv->regmap, info->offsets.frac, JH7110_PLL_FRAC_MASK,
				   val->frac << JH7110_PLL_FRAC_SHIFT);

	regmap_update_bits(priv->regmap, info->offsets.pd, info->masks.dacpd,
			   (u32)val->mode << info->shifts.dacpd);
	regmap_update_bits(priv->regmap, info->offsets.pd, info->masks.dsmpd,
			   (u32)val->mode << info->shifts.dsmpd);
	regmap_update_bits(priv->regmap, info->offsets.prediv, JH7110_PLL_PREDIV_MASK,
			   (u32)val->prediv << JH7110_PLL_PREDIV_SHIFT);
	regmap_update_bits(priv->regmap, info->offsets.fbdiv, info->masks.fbdiv,
			   val->fbdiv << info->shifts.fbdiv);
	regmap_update_bits(priv->regmap, info->offsets.frac, JH7110_PLL_POSTDIV1_MASK,
			   (u32)val->postdiv1 << JH7110_PLL_POSTDIV1_SHIFT);

	return 0;
}

#ifdef CONFIG_DEBUG_FS
static int jh7110_pll_registers_read(struct seq_file *s, void *unused)
{
	struct jh7110_pll_data *pll = s->private;
	struct jh7110_pll_priv *priv = jh7110_pll_priv_from(pll);
	struct jh7110_pll_regvals val;

	jh7110_pll_regvals_get(priv->regmap, &jh7110_plls[pll->idx], &val);

	seq_printf(s, "fbdiv=%u\n"
		      "frac=%u\n"
		      "prediv=%u\n"
		      "postdiv1=%u\n"
		      "dacpd=%u\n"
		      "dsmpd=%u\n",
		      val.fbdiv, val.frac, val.prediv, val.postdiv1,
		      val.dacpd, val.dsmpd);

	return 0;
}

static int jh7110_pll_registers_open(struct inode *inode, struct file *f)
{
	return single_open(f, jh7110_pll_registers_read, inode->i_private);
}

static const struct file_operations jh7110_pll_registers_ops = {
	.owner = THIS_MODULE,
	.open = jh7110_pll_registers_open,
	.release = single_release,
	.read = seq_read,
	.llseek = seq_lseek
};

static void jh7110_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
{
	struct jh7110_pll_data *pll = jh7110_pll_data_from(hw);

	debugfs_create_file("registers", 0400, dentry, pll,
			    &jh7110_pll_registers_ops);
}
#else
#define jh7110_pll_debug_init NULL
#endif

static const struct clk_ops jh7110_pll_ops = {
	.recalc_rate = jh7110_pll_recalc_rate,
	.determine_rate = jh7110_pll_determine_rate,
	.set_rate = jh7110_pll_set_rate,
	.debug_init = jh7110_pll_debug_init,
};

static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
{
	struct jh7110_pll_priv *priv = data;
	unsigned int idx = clkspec->args[0];

	if (idx < JH7110_PLLCLK_END)
		return &priv->pll[idx].hw;

	return ERR_PTR(-EINVAL);
}

static int jh7110_pll_probe(struct platform_device *pdev)
{
	struct jh7110_pll_priv *priv;
	unsigned int idx;
	int ret;

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

	priv->dev = &pdev->dev;
	priv->regmap = syscon_node_to_regmap(priv->dev->of_node->parent);
	if (IS_ERR(priv->regmap))
		return PTR_ERR(priv->regmap);

	for (idx = 0; idx < JH7110_PLLCLK_END; idx++) {
		struct clk_parent_data parents = {
			.index = 0,
		};
		struct clk_init_data init = {
			.name = jh7110_plls[idx].name,
			.ops = &jh7110_pll_ops,
			.parent_data = &parents,
			.num_parents = 1,
			.flags = 0,
		};
		struct jh7110_pll_data *pll = &priv->pll[idx];

		pll->hw.init = &init;
		pll->idx = idx;

		ret = devm_clk_hw_register(&pdev->dev, &pll->hw);
		if (ret)
			return ret;
	}

	return devm_of_clk_add_hw_provider(&pdev->dev, jh7110_pll_get, priv);
}

static const struct of_device_id jh7110_pll_match[] = {
	{ .compatible = "starfive,jh7110-pll" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, jh7110_pll_match);

static struct platform_driver jh7110_pll_driver = {
	.driver = {
		.name = "clk-starfive-jh7110-pll",
		.of_match_table = jh7110_pll_match,
	},
};
builtin_platform_driver_probe(jh7110_pll_driver, jh7110_pll_probe);
