// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Clock control for Cirrus EP93xx chips.
 * Copyright (C) 2021 Nikita Shubin <nikita.shubin@maquefel.me>
 *
 * Based on a rewrite of arch/arm/mach-ep93xx/clock.c:
 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
 */
#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt

#include <linux/bits.h>
#include <linux/cleanup.h>
#include <linux/clk-provider.h>
#include <linux/math.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>

#include <linux/soc/cirrus/ep93xx.h>
#include <dt-bindings/clock/cirrus,ep9301-syscon.h>

#include <asm/div64.h>

#define EP93XX_EXT_CLK_RATE		14745600
#define EP93XX_EXT_RTC_RATE		32768

#define EP93XX_SYSCON_POWER_STATE	0x00
#define EP93XX_SYSCON_PWRCNT		0x04
#define EP93XX_SYSCON_PWRCNT_UARTBAUD	BIT(29)
#define EP93XX_SYSCON_PWRCNT_USH_EN	28
#define EP93XX_SYSCON_PWRCNT_DMA_M2M1	27
#define EP93XX_SYSCON_PWRCNT_DMA_M2M0	26
#define EP93XX_SYSCON_PWRCNT_DMA_M2P8	25
#define EP93XX_SYSCON_PWRCNT_DMA_M2P9	24
#define EP93XX_SYSCON_PWRCNT_DMA_M2P6	23
#define EP93XX_SYSCON_PWRCNT_DMA_M2P7	22
#define EP93XX_SYSCON_PWRCNT_DMA_M2P4	21
#define EP93XX_SYSCON_PWRCNT_DMA_M2P5	20
#define EP93XX_SYSCON_PWRCNT_DMA_M2P2	19
#define EP93XX_SYSCON_PWRCNT_DMA_M2P3	18
#define EP93XX_SYSCON_PWRCNT_DMA_M2P0	17
#define EP93XX_SYSCON_PWRCNT_DMA_M2P1	16
#define EP93XX_SYSCON_CLKSET1		0x20
#define EP93XX_SYSCON_CLKSET1_NBYP1	BIT(23)
#define EP93XX_SYSCON_CLKSET2		0x24
#define EP93XX_SYSCON_CLKSET2_NBYP2	BIT(19)
#define EP93XX_SYSCON_CLKSET2_PLL2_EN	BIT(18)
#define EP93XX_SYSCON_DEVCFG		0x80
#define EP93XX_SYSCON_DEVCFG_U3EN	24
#define EP93XX_SYSCON_DEVCFG_U2EN	20
#define EP93XX_SYSCON_DEVCFG_U1EN	18
#define EP93XX_SYSCON_VIDCLKDIV		0x84
#define EP93XX_SYSCON_CLKDIV_ENABLE	15
#define EP93XX_SYSCON_CLKDIV_ESEL	BIT(14)
#define EP93XX_SYSCON_CLKDIV_PSEL	BIT(13)
#define EP93XX_SYSCON_CLKDIV_MASK	GENMASK(14, 13)
#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT	8
#define EP93XX_SYSCON_I2SCLKDIV		0x8c
#define EP93XX_SYSCON_I2SCLKDIV_SENA	31
#define EP93XX_SYSCON_I2SCLKDIV_ORIDE	BIT(29)
#define EP93XX_SYSCON_I2SCLKDIV_SPOL	BIT(19)
#define EP93XX_SYSCON_KEYTCHCLKDIV	0x90
#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN	31
#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV	16
#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN	15
#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV	0
#define EP93XX_SYSCON_CHIPID		0x94
#define EP93XX_SYSCON_CHIPID_ID		0x9213

#define EP93XX_FIXED_CLK_COUNT		21

static const char ep93xx_adc_divisors[] = { 16, 4 };
static const char ep93xx_sclk_divisors[] = { 2, 4 };
static const char ep93xx_lrclk_divisors[] = { 32, 64, 128 };

struct ep93xx_clk {
	struct clk_hw hw;
	u16 idx;
	u16 reg;
	u32 mask;
	u8 bit_idx;
	u8 shift;
	u8 width;
	u8 num_div;
	const char *div;
};

struct ep93xx_clk_priv {
	spinlock_t lock;
	struct ep93xx_regmap_adev *aux_dev;
	struct device *dev;
	void __iomem *base;
	struct regmap *map;
	struct clk_hw *fixed[EP93XX_FIXED_CLK_COUNT];
	struct ep93xx_clk reg[];
};

static struct ep93xx_clk *ep93xx_clk_from(struct clk_hw *hw)
{
	return container_of(hw, struct ep93xx_clk, hw);
}

static struct ep93xx_clk_priv *ep93xx_priv_from(struct ep93xx_clk *clk)
{
	return container_of(clk, struct ep93xx_clk_priv, reg[clk->idx]);
}

static void ep93xx_clk_write(struct ep93xx_clk_priv *priv, unsigned int reg, unsigned int val)
{
	struct ep93xx_regmap_adev *aux = priv->aux_dev;

	aux->write(aux->map, aux->lock, reg, val);
}

static int ep93xx_clk_is_enabled(struct clk_hw *hw)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;

	regmap_read(priv->map, clk->reg, &val);

	return !!(val & BIT(clk->bit_idx));
}

static int ep93xx_clk_enable(struct clk_hw *hw)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;

	guard(spinlock_irqsave)(&priv->lock);

	regmap_read(priv->map, clk->reg, &val);
	val |= BIT(clk->bit_idx);

	ep93xx_clk_write(priv, clk->reg, val);

	return 0;
}

static void ep93xx_clk_disable(struct clk_hw *hw)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;

	guard(spinlock_irqsave)(&priv->lock);

	regmap_read(priv->map, clk->reg, &val);
	val &= ~BIT(clk->bit_idx);

	ep93xx_clk_write(priv, clk->reg, val);
}

static const struct clk_ops clk_ep93xx_gate_ops = {
	.enable = ep93xx_clk_enable,
	.disable = ep93xx_clk_disable,
	.is_enabled = ep93xx_clk_is_enabled,
};

static int ep93xx_clk_register_gate(struct ep93xx_clk *clk,
				    const char *name,
				    struct clk_parent_data *parent_data,
				    unsigned long flags,
				    unsigned int reg,
				    u8 bit_idx)
{
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	struct clk_init_data init = { };

	init.name = name;
	init.ops = &clk_ep93xx_gate_ops;
	init.flags = flags;
	init.parent_data = parent_data;
	init.num_parents = 1;

	clk->reg = reg;
	clk->bit_idx = bit_idx;
	clk->hw.init = &init;

	return devm_clk_hw_register(priv->dev, &clk->hw);
}

static u8 ep93xx_mux_get_parent(struct clk_hw *hw)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;

	regmap_read(priv->map, clk->reg, &val);

	val &= EP93XX_SYSCON_CLKDIV_MASK;

	switch (val) {
	case EP93XX_SYSCON_CLKDIV_ESEL:
		return 1; /* PLL1 */
	case EP93XX_SYSCON_CLKDIV_MASK:
		return 2; /* PLL2 */
	default:
		return 0; /* XTALI */
	};
}

static int ep93xx_mux_set_parent_lock(struct clk_hw *hw, u8 index)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;

	if (index >= 3)
		return -EINVAL;

	guard(spinlock_irqsave)(&priv->lock);

	regmap_read(priv->map, clk->reg, &val);
	val &= ~(EP93XX_SYSCON_CLKDIV_MASK);
	val |= index > 0 ? EP93XX_SYSCON_CLKDIV_ESEL : 0;
	val |= index > 1 ? EP93XX_SYSCON_CLKDIV_PSEL : 0;

	ep93xx_clk_write(priv, clk->reg, val);

	return 0;
}

static bool is_best(unsigned long rate, unsigned long now,
		     unsigned long best)
{
	return abs_diff(rate, now) < abs_diff(rate, best);
}

static int ep93xx_mux_determine_rate(struct clk_hw *hw,
				struct clk_rate_request *req)
{
	unsigned long best_rate = 0, actual_rate, mclk_rate;
	unsigned long rate = req->rate;
	struct clk_hw *parent_best = NULL;
	unsigned long parent_rate_best;
	unsigned long parent_rate;
	int div, pdiv;
	unsigned int i;

	/*
	 * Try the two pll's and the external clock,
	 * because the valid predividers are 2, 2.5 and 3, we multiply
	 * all the clocks by 2 to avoid floating point math.
	 *
	 * This is based on the algorithm in the ep93xx raster guide:
	 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
	 *
	 */
	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
		struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);

		parent_rate = clk_hw_get_rate(parent);
		mclk_rate = parent_rate * 2;

		/* Try each predivider value */
		for (pdiv = 4; pdiv <= 6; pdiv++) {
			div = DIV_ROUND_CLOSEST(mclk_rate, rate * pdiv);
			if (!in_range(div, 1, 127))
				continue;

			actual_rate = DIV_ROUND_CLOSEST(mclk_rate, pdiv * div);
			if (is_best(rate, actual_rate, best_rate)) {
				best_rate = actual_rate;
				parent_rate_best = parent_rate;
				parent_best = parent;
			}
		}
	}

	if (!parent_best)
		return -EINVAL;

	req->best_parent_rate = parent_rate_best;
	req->best_parent_hw = parent_best;
	req->rate = best_rate;

	return 0;
}

static unsigned long ep93xx_ddiv_recalc_rate(struct clk_hw *hw,
						unsigned long parent_rate)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	unsigned int pdiv, div;
	u32 val;

	regmap_read(priv->map, clk->reg, &val);
	pdiv = (val >> EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) & GENMASK(1, 0);
	div = val & GENMASK(6, 0);
	if (!div)
		return 0;

	return DIV_ROUND_CLOSEST(parent_rate * 2, (pdiv + 3) * div);
}

static int ep93xx_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long parent_rate)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	int pdiv, div, npdiv, ndiv;
	unsigned long actual_rate, mclk_rate, rate_err = ULONG_MAX;
	u32 val;

	regmap_read(priv->map, clk->reg, &val);
	mclk_rate = parent_rate * 2;

	for (pdiv = 4; pdiv <= 6; pdiv++) {
		div = DIV_ROUND_CLOSEST(mclk_rate, rate * pdiv);
		if (!in_range(div, 1, 127))
			continue;

		actual_rate = DIV_ROUND_CLOSEST(mclk_rate, pdiv * div);
		if (abs(actual_rate - rate) < rate_err) {
			npdiv = pdiv - 3;
			ndiv = div;
			rate_err = abs(actual_rate - rate);
		}
	}

	if (rate_err == ULONG_MAX)
		return -EINVAL;

	/*
	 * Clear old dividers.
	 * Bit 7 is reserved bit in all ClkDiv registers.
	 */
	val &= ~(GENMASK(9, 0) & ~BIT(7));

	/* Set the new pdiv and div bits for the new clock rate */
	val |= (npdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | ndiv;

	ep93xx_clk_write(priv, clk->reg, val);

	return 0;
}

static const struct clk_ops clk_ddiv_ops = {
	.enable = ep93xx_clk_enable,
	.disable = ep93xx_clk_disable,
	.is_enabled = ep93xx_clk_is_enabled,
	.get_parent = ep93xx_mux_get_parent,
	.set_parent = ep93xx_mux_set_parent_lock,
	.determine_rate = ep93xx_mux_determine_rate,
	.recalc_rate = ep93xx_ddiv_recalc_rate,
	.set_rate = ep93xx_ddiv_set_rate,
};

static int ep93xx_clk_register_ddiv(struct ep93xx_clk *clk,
				const char *name,
				struct clk_parent_data *parent_data,
				u8 num_parents,
				unsigned int reg,
				u8 bit_idx)
{
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	struct clk_init_data init = { };

	init.name = name;
	init.ops = &clk_ddiv_ops;
	init.flags = 0;
	init.parent_data = parent_data;
	init.num_parents = num_parents;

	clk->reg = reg;
	clk->bit_idx = bit_idx;
	clk->hw.init = &init;

	return devm_clk_hw_register(priv->dev, &clk->hw);
}

static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;
	u8 index;

	regmap_read(priv->map, clk->reg, &val);
	index = (val & clk->mask) >> clk->shift;
	if (index >= clk->num_div)
		return 0;

	return DIV_ROUND_CLOSEST(parent_rate, clk->div[index]);
}

static int ep93xx_div_determine_rate(struct clk_hw *hw,
				     struct clk_rate_request *req)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	unsigned long best = 0, now;
	unsigned int i;

	for (i = 0; i < clk->num_div; i++) {
		if (req->rate * clk->div[i] == req->best_parent_rate)
			return 0;

		now = DIV_ROUND_CLOSEST(req->best_parent_rate, clk->div[i]);
		if (!best || is_best(req->rate, now, best))
			best = now;
	}

	req->rate = best;

	return 0;
}

static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long parent_rate)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	unsigned int i;
	u32 val;

	regmap_read(priv->map, clk->reg, &val);
	val &= ~clk->mask;
	for (i = 0; i < clk->num_div; i++)
		if (rate == DIV_ROUND_CLOSEST(parent_rate, clk->div[i]))
			break;

	if (i == clk->num_div)
		return -EINVAL;

	val |= i << clk->shift;

	ep93xx_clk_write(priv, clk->reg, val);

	return 0;
}

static const struct clk_ops ep93xx_div_ops = {
	.enable = ep93xx_clk_enable,
	.disable = ep93xx_clk_disable,
	.is_enabled = ep93xx_clk_is_enabled,
	.recalc_rate = ep93xx_div_recalc_rate,
	.determine_rate = ep93xx_div_determine_rate,
	.set_rate = ep93xx_div_set_rate,
};

static int ep93xx_register_div(struct ep93xx_clk *clk,
			       const char *name,
			       const struct clk_parent_data *parent_data,
			       unsigned int reg,
			       u8 enable_bit,
			       u8 shift,
			       u8 width,
			       const char *clk_divisors,
			       u8 num_div)
{
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	struct clk_init_data init = { };

	init.name = name;
	init.ops = &ep93xx_div_ops;
	init.flags = 0;
	init.parent_data = parent_data;
	init.num_parents = 1;

	clk->reg = reg;
	clk->bit_idx = enable_bit;
	clk->mask = GENMASK(shift + width - 1, shift);
	clk->shift = shift;
	clk->div = clk_divisors;
	clk->num_div = num_div;
	clk->hw.init = &init;

	return devm_clk_hw_register(priv->dev, &clk->hw);
}

struct ep93xx_gate {
	unsigned int idx;
	unsigned int bit;
	const char *name;
};

static const struct ep93xx_gate ep93xx_uarts[] = {
	{ EP93XX_CLK_UART1, EP93XX_SYSCON_DEVCFG_U1EN, "uart1" },
	{ EP93XX_CLK_UART2, EP93XX_SYSCON_DEVCFG_U2EN, "uart2" },
	{ EP93XX_CLK_UART3, EP93XX_SYSCON_DEVCFG_U3EN, "uart3" },
};

static int ep93xx_uart_clock_init(struct ep93xx_clk_priv *priv)
{
	struct clk_parent_data parent_data = { };
	unsigned int i, idx, clk_uart_div;
	struct ep93xx_clk *clk;
	u32 val;
	int ret;

	regmap_read(priv->map, EP93XX_SYSCON_PWRCNT, &val);
	if (val & EP93XX_SYSCON_PWRCNT_UARTBAUD)
		clk_uart_div = 1;
	else
		clk_uart_div = 2;

	priv->fixed[EP93XX_CLK_UART] =
		devm_clk_hw_register_fixed_factor_index(priv->dev, "uart",
							0, /* XTALI external clock */
							0, 1, clk_uart_div);
	parent_data.hw = priv->fixed[EP93XX_CLK_UART];

	/* parenting uart gate clocks to uart clock */
	for (i = 0; i < ARRAY_SIZE(ep93xx_uarts); i++) {
		idx = ep93xx_uarts[i].idx - EP93XX_CLK_UART1;
		clk = &priv->reg[idx];
		clk->idx = idx;
		ret = ep93xx_clk_register_gate(clk,
					ep93xx_uarts[i].name,
					&parent_data, CLK_SET_RATE_PARENT,
					EP93XX_SYSCON_DEVCFG,
					ep93xx_uarts[i].bit);
		if (ret)
			return dev_err_probe(priv->dev, ret,
					     "failed to register uart[%d] clock\n", i);
	}

	return 0;
}

static const struct ep93xx_gate ep93xx_dmas[] = {
	{ EP93XX_CLK_M2M0, EP93XX_SYSCON_PWRCNT_DMA_M2M0, "m2m0" },
	{ EP93XX_CLK_M2M1, EP93XX_SYSCON_PWRCNT_DMA_M2M1, "m2m1" },
	{ EP93XX_CLK_M2P0, EP93XX_SYSCON_PWRCNT_DMA_M2P0, "m2p0" },
	{ EP93XX_CLK_M2P1, EP93XX_SYSCON_PWRCNT_DMA_M2P1, "m2p1" },
	{ EP93XX_CLK_M2P2, EP93XX_SYSCON_PWRCNT_DMA_M2P2, "m2p2" },
	{ EP93XX_CLK_M2P3, EP93XX_SYSCON_PWRCNT_DMA_M2P3, "m2p3" },
	{ EP93XX_CLK_M2P4, EP93XX_SYSCON_PWRCNT_DMA_M2P4, "m2p4" },
	{ EP93XX_CLK_M2P5, EP93XX_SYSCON_PWRCNT_DMA_M2P5, "m2p5" },
	{ EP93XX_CLK_M2P6, EP93XX_SYSCON_PWRCNT_DMA_M2P6, "m2p6" },
	{ EP93XX_CLK_M2P7, EP93XX_SYSCON_PWRCNT_DMA_M2P7, "m2p7" },
	{ EP93XX_CLK_M2P8, EP93XX_SYSCON_PWRCNT_DMA_M2P8, "m2p8" },
	{ EP93XX_CLK_M2P9, EP93XX_SYSCON_PWRCNT_DMA_M2P9, "m2p9" },
};

static int ep93xx_dma_clock_init(struct ep93xx_clk_priv *priv)
{
	struct clk_parent_data parent_data = { };
	unsigned int i, idx;

	parent_data.hw = priv->fixed[EP93XX_CLK_HCLK];
	for (i = 0; i < ARRAY_SIZE(ep93xx_dmas); i++) {
		idx = ep93xx_dmas[i].idx;
		priv->fixed[idx] = devm_clk_hw_register_gate_parent_data(priv->dev,
					ep93xx_dmas[i].name,
					&parent_data, 0,
					priv->base + EP93XX_SYSCON_PWRCNT,
					ep93xx_dmas[i].bit,
					0,
					&priv->lock);
		if (IS_ERR(priv->fixed[idx]))
			return PTR_ERR(priv->fixed[idx]);
	}

	return 0;
}

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

	if (idx < EP93XX_CLK_UART1)
		return priv->fixed[idx];

	if (idx <= EP93XX_CLK_I2S_LRCLK)
		return &priv->reg[idx - EP93XX_CLK_UART1].hw;

	return ERR_PTR(-EINVAL);
}

/*
 * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
 */
static unsigned long calc_pll_rate(u64 rate, u32 config_word)
{
	rate *= ((config_word >> 11) & GENMASK(4, 0)) + 1;	/* X1FBD */
	rate *= ((config_word >> 5) & GENMASK(5, 0)) + 1;	/* X2FBD */
	do_div(rate, (config_word & GENMASK(4, 0)) + 1);	/* X2IPD */
	rate >>= (config_word >> 16) & GENMASK(1, 0);		/* PS */

	return rate;
}

static int ep93xx_plls_init(struct ep93xx_clk_priv *priv)
{
	static const char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
	static const char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
	static const char pclk_divisors[] = { 1, 2, 4, 8 };
	struct clk_parent_data xtali = { .index = 0 };
	unsigned int clk_f_div, clk_h_div, clk_p_div;
	unsigned long clk_pll1_rate, clk_pll2_rate;
	struct device *dev = priv->dev;
	struct clk_hw *hw, *pll1;
	u32 value;

	/* Determine the bootloader configured pll1 rate */
	regmap_read(priv->map, EP93XX_SYSCON_CLKSET1, &value);

	if (value & EP93XX_SYSCON_CLKSET1_NBYP1)
		clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
	else
		clk_pll1_rate = EP93XX_EXT_CLK_RATE;

	pll1 = devm_clk_hw_register_fixed_rate_parent_data(dev, "pll1", &xtali,
								  0, clk_pll1_rate);
	if (IS_ERR(pll1))
		return PTR_ERR(pll1);

	priv->fixed[EP93XX_CLK_PLL1] = pll1;

	/* Initialize the pll1 derived clocks */
	clk_f_div = fclk_divisors[(value >> 25) & GENMASK(2, 0)];
	clk_h_div = hclk_divisors[(value >> 20) & GENMASK(2, 0)];
	clk_p_div = pclk_divisors[(value >> 18) & GENMASK(1, 0)];

	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "fclk", pll1, 0, 1, clk_f_div);
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	priv->fixed[EP93XX_CLK_FCLK] = hw;

	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "hclk", pll1, 0, 1, clk_h_div);
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	priv->fixed[EP93XX_CLK_HCLK] = hw;

	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "pclk", hw, 0, 1, clk_p_div);
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	priv->fixed[EP93XX_CLK_PCLK] = hw;

	/* Determine the bootloader configured pll2 rate */
	regmap_read(priv->map, EP93XX_SYSCON_CLKSET2, &value);
	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
		clk_pll2_rate = EP93XX_EXT_CLK_RATE;
	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
		clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
	else
		clk_pll2_rate = 0;

	hw = devm_clk_hw_register_fixed_rate_parent_data(dev, "pll2", &xtali,
								0, clk_pll2_rate);
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	priv->fixed[EP93XX_CLK_PLL2] = hw;

	return 0;
}

static int ep93xx_clk_probe(struct auxiliary_device *adev,
			       const struct auxiliary_device_id *id)
{
	struct ep93xx_regmap_adev *rdev = to_ep93xx_regmap_adev(adev);
	struct clk_parent_data xtali = { .index = 0 };
	struct clk_parent_data ddiv_pdata[3] = { };
	unsigned int clk_spi_div, clk_usb_div;
	struct clk_parent_data pdata = {};
	struct device *dev = &adev->dev;
	struct ep93xx_clk_priv *priv;
	struct ep93xx_clk *clk;
	struct clk_hw *hw;
	unsigned int idx;
	int ret;
	u32 value;

	priv = devm_kzalloc(dev, struct_size(priv, reg, 10), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	spin_lock_init(&priv->lock);
	priv->dev = dev;
	priv->aux_dev = rdev;
	priv->map = rdev->map;
	priv->base = rdev->base;

	ret = ep93xx_plls_init(priv);
	if (ret)
		return ret;

	regmap_read(priv->map, EP93XX_SYSCON_CLKSET2, &value);
	clk_usb_div = (value >> 28 & GENMASK(3, 0)) + 1;
	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "usb_clk",
							 priv->fixed[EP93XX_CLK_PLL2], 0, 1,
							 clk_usb_div);
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	priv->fixed[EP93XX_CLK_USB] = hw;

	ret = ep93xx_uart_clock_init(priv);
	if (ret)
		return ret;

	ret = ep93xx_dma_clock_init(priv);
	if (ret)
		return ret;

	clk_spi_div = id->driver_data;
	hw = devm_clk_hw_register_fixed_factor_index(dev, "ep93xx-spi.0",
						     0, /* XTALI external clock */
						     0, 1, clk_spi_div);
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	priv->fixed[EP93XX_CLK_SPI] = hw;

	/* PWM clock */
	hw = devm_clk_hw_register_fixed_factor_index(dev, "pwm_clk", 0, /* XTALI external clock */
						     0, 1, 1);
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	priv->fixed[EP93XX_CLK_PWM] = hw;

	/* USB clock */
	pdata.hw = priv->fixed[EP93XX_CLK_USB];
	hw = devm_clk_hw_register_gate_parent_data(priv->dev, "ohci-platform", &pdata,
						   0, priv->base + EP93XX_SYSCON_PWRCNT,
						   EP93XX_SYSCON_PWRCNT_USH_EN, 0,
						   &priv->lock);
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	priv->fixed[EP93XX_CLK_USB] = hw;

	ddiv_pdata[0].index = 0; /* XTALI external clock */
	ddiv_pdata[1].hw = priv->fixed[EP93XX_CLK_PLL1];
	ddiv_pdata[2].hw = priv->fixed[EP93XX_CLK_PLL2];

	/* touchscreen/ADC clock */
	idx = EP93XX_CLK_ADC - EP93XX_CLK_UART1;
	clk = &priv->reg[idx];
	clk->idx = idx;
	ret = ep93xx_register_div(clk, "ep93xx-adc", &xtali,
				EP93XX_SYSCON_KEYTCHCLKDIV,
				EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
				EP93XX_SYSCON_KEYTCHCLKDIV_ADIV,
				1,
				ep93xx_adc_divisors,
				ARRAY_SIZE(ep93xx_adc_divisors));


	/* keypad clock */
	idx = EP93XX_CLK_KEYPAD - EP93XX_CLK_UART1;
	clk = &priv->reg[idx];
	clk->idx = idx;
	ret = ep93xx_register_div(clk, "ep93xx-keypad", &xtali,
				EP93XX_SYSCON_KEYTCHCLKDIV,
				EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
				EP93XX_SYSCON_KEYTCHCLKDIV_KDIV,
				1,
				ep93xx_adc_divisors,
				ARRAY_SIZE(ep93xx_adc_divisors));

	/*
	 * On reset PDIV and VDIV is set to zero, while PDIV zero
	 * means clock disable, VDIV shouldn't be zero.
	 * So we set both video and i2s dividers to minimum.
	 * ENA - Enable CLK divider.
	 * PDIV - 00 - Disable clock
	 * VDIV - at least 2
	 */

	/* Check and enable video clk registers */
	regmap_read(priv->map, EP93XX_SYSCON_VIDCLKDIV, &value);
	value |= BIT(EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
	ep93xx_clk_write(priv, EP93XX_SYSCON_VIDCLKDIV, value);

	/* Check and enable i2s clk registers */
	regmap_read(priv->map, EP93XX_SYSCON_I2SCLKDIV, &value);
	value |= BIT(EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;

	/*
	 * Override the SAI_MSTR_CLK_CFG from the I2S block and use the
	 * I2SClkDiv Register settings. LRCLK transitions on the falling SCLK
	 * edge.
	 */
	value |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
	ep93xx_clk_write(priv, EP93XX_SYSCON_I2SCLKDIV, value);

	/* video clk */
	idx = EP93XX_CLK_VIDEO - EP93XX_CLK_UART1;
	clk = &priv->reg[idx];
	clk->idx = idx;
	ret = ep93xx_clk_register_ddiv(clk, "ep93xx-fb",
				ddiv_pdata, ARRAY_SIZE(ddiv_pdata),
				EP93XX_SYSCON_VIDCLKDIV,
				EP93XX_SYSCON_CLKDIV_ENABLE);

	/* i2s clk */
	idx = EP93XX_CLK_I2S_MCLK - EP93XX_CLK_UART1;
	clk = &priv->reg[idx];
	clk->idx = idx;
	ret = ep93xx_clk_register_ddiv(clk, "mclk",
				ddiv_pdata, ARRAY_SIZE(ddiv_pdata),
				EP93XX_SYSCON_I2SCLKDIV,
				EP93XX_SYSCON_CLKDIV_ENABLE);

	/* i2s sclk */
	idx = EP93XX_CLK_I2S_SCLK - EP93XX_CLK_UART1;
	clk = &priv->reg[idx];
	clk->idx = idx;
	pdata.hw = &priv->reg[EP93XX_CLK_I2S_MCLK - EP93XX_CLK_UART1].hw;
	ret = ep93xx_register_div(clk, "sclk", &pdata,
				EP93XX_SYSCON_I2SCLKDIV,
				EP93XX_SYSCON_I2SCLKDIV_SENA,
				16, /* EP93XX_I2SCLKDIV_SDIV_SHIFT */
				1,  /* EP93XX_I2SCLKDIV_SDIV_WIDTH */
				ep93xx_sclk_divisors,
				ARRAY_SIZE(ep93xx_sclk_divisors));

	/* i2s lrclk */
	idx = EP93XX_CLK_I2S_LRCLK - EP93XX_CLK_UART1;
	clk = &priv->reg[idx];
	clk->idx = idx;
	pdata.hw = &priv->reg[EP93XX_CLK_I2S_SCLK - EP93XX_CLK_UART1].hw;
	ret = ep93xx_register_div(clk, "lrclk", &pdata,
				EP93XX_SYSCON_I2SCLKDIV,
				EP93XX_SYSCON_I2SCLKDIV_SENA,
				17, /* EP93XX_I2SCLKDIV_LRDIV32_SHIFT */
				2,  /* EP93XX_I2SCLKDIV_LRDIV32_WIDTH */
				ep93xx_lrclk_divisors,
				ARRAY_SIZE(ep93xx_lrclk_divisors));

	/* IrDa clk uses same pattern but no init code presents in original clock driver */
	return devm_of_clk_add_hw_provider(priv->dev, of_clk_ep93xx_get, priv);
}

static const struct auxiliary_device_id ep93xx_clk_ids[] = {
	{ .name = "soc_ep93xx.clk-ep93xx", .driver_data = 2, },
	{ .name = "soc_ep93xx.clk-ep93xx.e2", .driver_data = 1, },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(auxiliary, ep93xx_clk_ids);

static struct auxiliary_driver ep93xx_clk_driver = {
	.probe		= ep93xx_clk_probe,
	.id_table	= ep93xx_clk_ids,
};
module_auxiliary_driver(ep93xx_clk_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Nikita Shubin <nikita.shubin@maquefel.me>");
MODULE_DESCRIPTION("Clock control for Cirrus EP93xx chips");
