// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum pll clock driver
//
// Copyright (C) 2015~2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include "pll.h"

#define CLK_PLL_1M	1000000
#define CLK_PLL_10M	(CLK_PLL_1M * 10)

#define pindex(pll, member)		\
	(pll->factors[member].shift / (8 * sizeof(pll->regs_num)))

#define pshift(pll, member)		\
	(pll->factors[member].shift % (8 * sizeof(pll->regs_num)))

#define pwidth(pll, member)		\
	pll->factors[member].width

#define pmask(pll, member)					\
	((pwidth(pll, member)) ?				\
	GENMASK(pwidth(pll, member) + pshift(pll, member) - 1,	\
	pshift(pll, member)) : 0)

#define pinternal(pll, cfg, member)	\
	(cfg[pindex(pll, member)] & pmask(pll, member))

#define pinternal_val(pll, cfg, member)	\
	(pinternal(pll, cfg, member) >> pshift(pll, member))

static inline unsigned int
sprd_pll_read(const struct sprd_pll *pll, u8 index)
{
	const struct sprd_clk_common *common = &pll->common;
	unsigned int val = 0;

	if (WARN_ON(index >= pll->regs_num))
		return 0;

	regmap_read(common->regmap, common->reg + index * 4, &val);

	return val;
}

static inline void
sprd_pll_write(const struct sprd_pll *pll, u8 index,
				  u32 msk, u32 val)
{
	const struct sprd_clk_common *common = &pll->common;
	unsigned int offset, reg;
	int ret = 0;

	if (WARN_ON(index >= pll->regs_num))
		return;

	offset = common->reg + index * 4;
	ret = regmap_read(common->regmap, offset, &reg);
	if (!ret)
		regmap_write(common->regmap, offset, (reg & ~msk) | val);
}

static unsigned long pll_get_refin(const struct sprd_pll *pll)
{
	u32 shift, mask, index, refin_id = 3;
	const unsigned long refin[4] = { 2, 4, 13, 26 };

	if (pwidth(pll, PLL_REFIN)) {
		index = pindex(pll, PLL_REFIN);
		shift = pshift(pll, PLL_REFIN);
		mask = pmask(pll, PLL_REFIN);
		refin_id = (sprd_pll_read(pll, index) & mask) >> shift;
		if (refin_id > 3)
			refin_id = 3;
	}

	return refin[refin_id];
}

static u32 pll_get_ibias(u64 rate, const u64 *table)
{
	u32 i, num = table[0];

	for (i = 1; i < num + 1; i++)
		if (rate <= table[i])
			break;

	return (i == num + 1) ? num : i;
}

static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll,
					   unsigned long parent_rate)
{
	u32 *cfg;
	u32 i, mask, regs_num = pll->regs_num;
	unsigned long rate, nint, kint = 0;
	u64 refin;
	u16 k1, k2;

	cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
	if (!cfg)
		return -ENOMEM;

	for (i = 0; i < regs_num; i++)
		cfg[i] = sprd_pll_read(pll, i);

	refin = pll_get_refin(pll);

	if (pinternal(pll, cfg, PLL_PREDIV))
		refin = refin * 2;

	if (pwidth(pll, PLL_POSTDIV) &&
	    ((pll->fflag == 1 && pinternal(pll, cfg, PLL_POSTDIV)) ||
	     (!pll->fflag && !pinternal(pll, cfg, PLL_POSTDIV))))
		refin = refin / 2;

	if (!pinternal(pll, cfg, PLL_DIV_S)) {
		rate = refin * pinternal_val(pll, cfg, PLL_N) * CLK_PLL_10M;
	} else {
		nint = pinternal_val(pll, cfg, PLL_NINT);
		if (pinternal(pll, cfg, PLL_SDM_EN))
			kint = pinternal_val(pll, cfg, PLL_KINT);

		mask = pmask(pll, PLL_KINT);

		k1 = pll->k1;
		k2 = pll->k2;
		rate = DIV_ROUND_CLOSEST_ULL(refin * kint * k1,
					 ((mask >> __ffs(mask)) + 1)) *
					 k2 + refin * nint * CLK_PLL_1M;
	}

	return rate;
}

#define SPRD_PLL_WRITE_CHECK(pll, i, mask, val)		\
	(((sprd_pll_read(pll, i) & mask) == val) ? 0 : (-EFAULT))

static int _sprd_pll_set_rate(const struct sprd_pll *pll,
			      unsigned long rate,
			      unsigned long parent_rate)
{
	struct reg_cfg *cfg;
	int ret = 0;
	u32 mask, shift, width, ibias_val, index;
	u32 regs_num = pll->regs_num, i = 0;
	unsigned long kint, nint;
	u64 tmp, refin, fvco = rate;

	cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
	if (!cfg)
		return -ENOMEM;

	refin = pll_get_refin(pll);

	mask = pmask(pll, PLL_PREDIV);
	index = pindex(pll, PLL_PREDIV);
	width = pwidth(pll, PLL_PREDIV);
	if (width && (sprd_pll_read(pll, index) & mask))
		refin = refin * 2;

	mask = pmask(pll, PLL_POSTDIV);
	index = pindex(pll, PLL_POSTDIV);
	width = pwidth(pll, PLL_POSTDIV);
	cfg[index].msk = mask;
	if (width && ((pll->fflag == 1 && fvco <= pll->fvco) ||
		      (pll->fflag == 0 && fvco > pll->fvco)))
		cfg[index].val |= mask;

	if (width && fvco <= pll->fvco)
		fvco = fvco * 2;

	mask = pmask(pll, PLL_DIV_S);
	index = pindex(pll, PLL_DIV_S);
	cfg[index].val |= mask;
	cfg[index].msk |= mask;

	mask = pmask(pll, PLL_SDM_EN);
	index = pindex(pll, PLL_SDM_EN);
	cfg[index].val |= mask;
	cfg[index].msk |= mask;

	nint = do_div(fvco, refin * CLK_PLL_1M);
	mask = pmask(pll, PLL_NINT);
	index = pindex(pll, PLL_NINT);
	shift = pshift(pll, PLL_NINT);
	cfg[index].val |= (nint << shift) & mask;
	cfg[index].msk |= mask;

	mask = pmask(pll, PLL_KINT);
	index = pindex(pll, PLL_KINT);
	width = pwidth(pll, PLL_KINT);
	shift = pshift(pll, PLL_KINT);
	tmp = fvco - refin * nint * CLK_PLL_1M;
	tmp = do_div(tmp, 10000) * ((mask >> shift) + 1);
	kint = DIV_ROUND_CLOSEST_ULL(tmp, refin * 100);
	cfg[index].val |= (kint << shift) & mask;
	cfg[index].msk |= mask;

	ibias_val = pll_get_ibias(fvco, pll->itable);

	mask = pmask(pll, PLL_IBIAS);
	index = pindex(pll, PLL_IBIAS);
	shift = pshift(pll, PLL_IBIAS);
	cfg[index].val |= ibias_val << shift & mask;
	cfg[index].msk |= mask;

	for (i = 0; i < regs_num; i++) {
		if (cfg[i].msk) {
			sprd_pll_write(pll, i, cfg[i].msk, cfg[i].val);
			ret |= SPRD_PLL_WRITE_CHECK(pll, i, cfg[i].msk,
						   cfg[i].val);
		}
	}

	if (!ret)
		udelay(pll->udelay);

	return ret;
}

static unsigned long sprd_pll_recalc_rate(struct clk_hw *hw,
					  unsigned long parent_rate)
{
	struct sprd_pll *pll = hw_to_sprd_pll(hw);

	return _sprd_pll_recalc_rate(pll, parent_rate);
}

static int sprd_pll_set_rate(struct clk_hw *hw,
			     unsigned long rate,
			     unsigned long parent_rate)
{
	struct sprd_pll *pll = hw_to_sprd_pll(hw);

	return _sprd_pll_set_rate(pll, rate, parent_rate);
}

static int sprd_pll_clk_prepare(struct clk_hw *hw)
{
	struct sprd_pll *pll = hw_to_sprd_pll(hw);

	udelay(pll->udelay);

	return 0;
}

static long sprd_pll_round_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long *prate)
{
	return rate;
}

const struct clk_ops sprd_pll_ops = {
	.prepare = sprd_pll_clk_prepare,
	.recalc_rate = sprd_pll_recalc_rate,
	.round_rate = sprd_pll_round_rate,
	.set_rate = sprd_pll_set_rate,
};
EXPORT_SYMBOL_GPL(sprd_pll_ops);
