xref: /linux/drivers/clk/clk-ep93xx.c (revision 3fd6c59042dbba50391e30862beac979491145fe)
18a6b7e2bSNikita Shubin // SPDX-License-Identifier: GPL-2.0-or-later
28a6b7e2bSNikita Shubin /*
38a6b7e2bSNikita Shubin  * Clock control for Cirrus EP93xx chips.
48a6b7e2bSNikita Shubin  * Copyright (C) 2021 Nikita Shubin <nikita.shubin@maquefel.me>
58a6b7e2bSNikita Shubin  *
68a6b7e2bSNikita Shubin  * Based on a rewrite of arch/arm/mach-ep93xx/clock.c:
78a6b7e2bSNikita Shubin  * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
88a6b7e2bSNikita Shubin  */
98a6b7e2bSNikita Shubin #define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
108a6b7e2bSNikita Shubin 
118a6b7e2bSNikita Shubin #include <linux/bits.h>
128a6b7e2bSNikita Shubin #include <linux/cleanup.h>
138a6b7e2bSNikita Shubin #include <linux/clk-provider.h>
148a6b7e2bSNikita Shubin #include <linux/math.h>
158a6b7e2bSNikita Shubin #include <linux/platform_device.h>
168a6b7e2bSNikita Shubin #include <linux/regmap.h>
178a6b7e2bSNikita Shubin #include <linux/spinlock.h>
188a6b7e2bSNikita Shubin 
198a6b7e2bSNikita Shubin #include <linux/soc/cirrus/ep93xx.h>
208a6b7e2bSNikita Shubin #include <dt-bindings/clock/cirrus,ep9301-syscon.h>
218a6b7e2bSNikita Shubin 
228a6b7e2bSNikita Shubin #include <asm/div64.h>
238a6b7e2bSNikita Shubin 
248a6b7e2bSNikita Shubin #define EP93XX_EXT_CLK_RATE		14745600
258a6b7e2bSNikita Shubin #define EP93XX_EXT_RTC_RATE		32768
268a6b7e2bSNikita Shubin 
278a6b7e2bSNikita Shubin #define EP93XX_SYSCON_POWER_STATE	0x00
288a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT		0x04
298a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_UARTBAUD	BIT(29)
308a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_USH_EN	28
318a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2M1	27
328a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2M0	26
338a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P8	25
348a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P9	24
358a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P6	23
368a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P7	22
378a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P4	21
388a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P5	20
398a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P2	19
408a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P3	18
418a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P0	17
428a6b7e2bSNikita Shubin #define EP93XX_SYSCON_PWRCNT_DMA_M2P1	16
438a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKSET1		0x20
448a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKSET1_NBYP1	BIT(23)
458a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKSET2		0x24
468a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKSET2_NBYP2	BIT(19)
478a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKSET2_PLL2_EN	BIT(18)
488a6b7e2bSNikita Shubin #define EP93XX_SYSCON_DEVCFG		0x80
498a6b7e2bSNikita Shubin #define EP93XX_SYSCON_DEVCFG_U3EN	24
508a6b7e2bSNikita Shubin #define EP93XX_SYSCON_DEVCFG_U2EN	20
518a6b7e2bSNikita Shubin #define EP93XX_SYSCON_DEVCFG_U1EN	18
528a6b7e2bSNikita Shubin #define EP93XX_SYSCON_VIDCLKDIV		0x84
538a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKDIV_ENABLE	15
548a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKDIV_ESEL	BIT(14)
558a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKDIV_PSEL	BIT(13)
568a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKDIV_MASK	GENMASK(14, 13)
578a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT	8
588a6b7e2bSNikita Shubin #define EP93XX_SYSCON_I2SCLKDIV		0x8c
598a6b7e2bSNikita Shubin #define EP93XX_SYSCON_I2SCLKDIV_SENA	31
608a6b7e2bSNikita Shubin #define EP93XX_SYSCON_I2SCLKDIV_ORIDE	BIT(29)
618a6b7e2bSNikita Shubin #define EP93XX_SYSCON_I2SCLKDIV_SPOL	BIT(19)
628a6b7e2bSNikita Shubin #define EP93XX_SYSCON_KEYTCHCLKDIV	0x90
638a6b7e2bSNikita Shubin #define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN	31
648a6b7e2bSNikita Shubin #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV	16
658a6b7e2bSNikita Shubin #define EP93XX_SYSCON_KEYTCHCLKDIV_KEN	15
668a6b7e2bSNikita Shubin #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV	0
678a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CHIPID		0x94
688a6b7e2bSNikita Shubin #define EP93XX_SYSCON_CHIPID_ID		0x9213
698a6b7e2bSNikita Shubin 
708a6b7e2bSNikita Shubin #define EP93XX_FIXED_CLK_COUNT		21
718a6b7e2bSNikita Shubin 
728a6b7e2bSNikita Shubin static const char ep93xx_adc_divisors[] = { 16, 4 };
738a6b7e2bSNikita Shubin static const char ep93xx_sclk_divisors[] = { 2, 4 };
748a6b7e2bSNikita Shubin static const char ep93xx_lrclk_divisors[] = { 32, 64, 128 };
758a6b7e2bSNikita Shubin 
768a6b7e2bSNikita Shubin struct ep93xx_clk {
778a6b7e2bSNikita Shubin 	struct clk_hw hw;
788a6b7e2bSNikita Shubin 	u16 idx;
798a6b7e2bSNikita Shubin 	u16 reg;
808a6b7e2bSNikita Shubin 	u32 mask;
818a6b7e2bSNikita Shubin 	u8 bit_idx;
828a6b7e2bSNikita Shubin 	u8 shift;
838a6b7e2bSNikita Shubin 	u8 width;
848a6b7e2bSNikita Shubin 	u8 num_div;
858a6b7e2bSNikita Shubin 	const char *div;
868a6b7e2bSNikita Shubin };
878a6b7e2bSNikita Shubin 
888a6b7e2bSNikita Shubin struct ep93xx_clk_priv {
898a6b7e2bSNikita Shubin 	spinlock_t lock;
908a6b7e2bSNikita Shubin 	struct ep93xx_regmap_adev *aux_dev;
918a6b7e2bSNikita Shubin 	struct device *dev;
928a6b7e2bSNikita Shubin 	void __iomem *base;
938a6b7e2bSNikita Shubin 	struct regmap *map;
948a6b7e2bSNikita Shubin 	struct clk_hw *fixed[EP93XX_FIXED_CLK_COUNT];
958a6b7e2bSNikita Shubin 	struct ep93xx_clk reg[];
968a6b7e2bSNikita Shubin };
978a6b7e2bSNikita Shubin 
ep93xx_clk_from(struct clk_hw * hw)988a6b7e2bSNikita Shubin static struct ep93xx_clk *ep93xx_clk_from(struct clk_hw *hw)
998a6b7e2bSNikita Shubin {
1008a6b7e2bSNikita Shubin 	return container_of(hw, struct ep93xx_clk, hw);
1018a6b7e2bSNikita Shubin }
1028a6b7e2bSNikita Shubin 
ep93xx_priv_from(struct ep93xx_clk * clk)1038a6b7e2bSNikita Shubin static struct ep93xx_clk_priv *ep93xx_priv_from(struct ep93xx_clk *clk)
1048a6b7e2bSNikita Shubin {
1058a6b7e2bSNikita Shubin 	return container_of(clk, struct ep93xx_clk_priv, reg[clk->idx]);
1068a6b7e2bSNikita Shubin }
1078a6b7e2bSNikita Shubin 
ep93xx_clk_write(struct ep93xx_clk_priv * priv,unsigned int reg,unsigned int val)1088a6b7e2bSNikita Shubin static void ep93xx_clk_write(struct ep93xx_clk_priv *priv, unsigned int reg, unsigned int val)
1098a6b7e2bSNikita Shubin {
1108a6b7e2bSNikita Shubin 	struct ep93xx_regmap_adev *aux = priv->aux_dev;
1118a6b7e2bSNikita Shubin 
1128a6b7e2bSNikita Shubin 	aux->write(aux->map, aux->lock, reg, val);
1138a6b7e2bSNikita Shubin }
1148a6b7e2bSNikita Shubin 
ep93xx_clk_is_enabled(struct clk_hw * hw)1158a6b7e2bSNikita Shubin static int ep93xx_clk_is_enabled(struct clk_hw *hw)
1168a6b7e2bSNikita Shubin {
1178a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
1188a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
1198a6b7e2bSNikita Shubin 	u32 val;
1208a6b7e2bSNikita Shubin 
1218a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
1228a6b7e2bSNikita Shubin 
1238a6b7e2bSNikita Shubin 	return !!(val & BIT(clk->bit_idx));
1248a6b7e2bSNikita Shubin }
1258a6b7e2bSNikita Shubin 
ep93xx_clk_enable(struct clk_hw * hw)1268a6b7e2bSNikita Shubin static int ep93xx_clk_enable(struct clk_hw *hw)
1278a6b7e2bSNikita Shubin {
1288a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
1298a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
1308a6b7e2bSNikita Shubin 	u32 val;
1318a6b7e2bSNikita Shubin 
1328a6b7e2bSNikita Shubin 	guard(spinlock_irqsave)(&priv->lock);
1338a6b7e2bSNikita Shubin 
1348a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
1358a6b7e2bSNikita Shubin 	val |= BIT(clk->bit_idx);
1368a6b7e2bSNikita Shubin 
1378a6b7e2bSNikita Shubin 	ep93xx_clk_write(priv, clk->reg, val);
1388a6b7e2bSNikita Shubin 
1398a6b7e2bSNikita Shubin 	return 0;
1408a6b7e2bSNikita Shubin }
1418a6b7e2bSNikita Shubin 
ep93xx_clk_disable(struct clk_hw * hw)1428a6b7e2bSNikita Shubin static void ep93xx_clk_disable(struct clk_hw *hw)
1438a6b7e2bSNikita Shubin {
1448a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
1458a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
1468a6b7e2bSNikita Shubin 	u32 val;
1478a6b7e2bSNikita Shubin 
1488a6b7e2bSNikita Shubin 	guard(spinlock_irqsave)(&priv->lock);
1498a6b7e2bSNikita Shubin 
1508a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
1518a6b7e2bSNikita Shubin 	val &= ~BIT(clk->bit_idx);
1528a6b7e2bSNikita Shubin 
1538a6b7e2bSNikita Shubin 	ep93xx_clk_write(priv, clk->reg, val);
1548a6b7e2bSNikita Shubin }
1558a6b7e2bSNikita Shubin 
1568a6b7e2bSNikita Shubin static const struct clk_ops clk_ep93xx_gate_ops = {
1578a6b7e2bSNikita Shubin 	.enable = ep93xx_clk_enable,
1588a6b7e2bSNikita Shubin 	.disable = ep93xx_clk_disable,
1598a6b7e2bSNikita Shubin 	.is_enabled = ep93xx_clk_is_enabled,
1608a6b7e2bSNikita Shubin };
1618a6b7e2bSNikita Shubin 
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)1628a6b7e2bSNikita Shubin static int ep93xx_clk_register_gate(struct ep93xx_clk *clk,
1638a6b7e2bSNikita Shubin 				    const char *name,
1648a6b7e2bSNikita Shubin 				    struct clk_parent_data *parent_data,
1658a6b7e2bSNikita Shubin 				    unsigned long flags,
1668a6b7e2bSNikita Shubin 				    unsigned int reg,
1678a6b7e2bSNikita Shubin 				    u8 bit_idx)
1688a6b7e2bSNikita Shubin {
1698a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
1708a6b7e2bSNikita Shubin 	struct clk_init_data init = { };
1718a6b7e2bSNikita Shubin 
1728a6b7e2bSNikita Shubin 	init.name = name;
1738a6b7e2bSNikita Shubin 	init.ops = &clk_ep93xx_gate_ops;
1748a6b7e2bSNikita Shubin 	init.flags = flags;
1758a6b7e2bSNikita Shubin 	init.parent_data = parent_data;
1768a6b7e2bSNikita Shubin 	init.num_parents = 1;
1778a6b7e2bSNikita Shubin 
1788a6b7e2bSNikita Shubin 	clk->reg = reg;
1798a6b7e2bSNikita Shubin 	clk->bit_idx = bit_idx;
1808a6b7e2bSNikita Shubin 	clk->hw.init = &init;
1818a6b7e2bSNikita Shubin 
1828a6b7e2bSNikita Shubin 	return devm_clk_hw_register(priv->dev, &clk->hw);
1838a6b7e2bSNikita Shubin }
1848a6b7e2bSNikita Shubin 
ep93xx_mux_get_parent(struct clk_hw * hw)1858a6b7e2bSNikita Shubin static u8 ep93xx_mux_get_parent(struct clk_hw *hw)
1868a6b7e2bSNikita Shubin {
1878a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
1888a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
1898a6b7e2bSNikita Shubin 	u32 val;
1908a6b7e2bSNikita Shubin 
1918a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
1928a6b7e2bSNikita Shubin 
1938a6b7e2bSNikita Shubin 	val &= EP93XX_SYSCON_CLKDIV_MASK;
1948a6b7e2bSNikita Shubin 
1958a6b7e2bSNikita Shubin 	switch (val) {
1968a6b7e2bSNikita Shubin 	case EP93XX_SYSCON_CLKDIV_ESEL:
1978a6b7e2bSNikita Shubin 		return 1; /* PLL1 */
1988a6b7e2bSNikita Shubin 	case EP93XX_SYSCON_CLKDIV_MASK:
1998a6b7e2bSNikita Shubin 		return 2; /* PLL2 */
2008a6b7e2bSNikita Shubin 	default:
2018a6b7e2bSNikita Shubin 		return 0; /* XTALI */
2028a6b7e2bSNikita Shubin 	};
2038a6b7e2bSNikita Shubin }
2048a6b7e2bSNikita Shubin 
ep93xx_mux_set_parent_lock(struct clk_hw * hw,u8 index)2058a6b7e2bSNikita Shubin static int ep93xx_mux_set_parent_lock(struct clk_hw *hw, u8 index)
2068a6b7e2bSNikita Shubin {
2078a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
2088a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
2098a6b7e2bSNikita Shubin 	u32 val;
2108a6b7e2bSNikita Shubin 
2118a6b7e2bSNikita Shubin 	if (index >= 3)
2128a6b7e2bSNikita Shubin 		return -EINVAL;
2138a6b7e2bSNikita Shubin 
2148a6b7e2bSNikita Shubin 	guard(spinlock_irqsave)(&priv->lock);
2158a6b7e2bSNikita Shubin 
2168a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
2178a6b7e2bSNikita Shubin 	val &= ~(EP93XX_SYSCON_CLKDIV_MASK);
2188a6b7e2bSNikita Shubin 	val |= index > 0 ? EP93XX_SYSCON_CLKDIV_ESEL : 0;
2198a6b7e2bSNikita Shubin 	val |= index > 1 ? EP93XX_SYSCON_CLKDIV_PSEL : 0;
2208a6b7e2bSNikita Shubin 
2218a6b7e2bSNikita Shubin 	ep93xx_clk_write(priv, clk->reg, val);
2228a6b7e2bSNikita Shubin 
2238a6b7e2bSNikita Shubin 	return 0;
2248a6b7e2bSNikita Shubin }
2258a6b7e2bSNikita Shubin 
is_best(unsigned long rate,unsigned long now,unsigned long best)2268a6b7e2bSNikita Shubin static bool is_best(unsigned long rate, unsigned long now,
2278a6b7e2bSNikita Shubin 		     unsigned long best)
2288a6b7e2bSNikita Shubin {
2298a6b7e2bSNikita Shubin 	return abs_diff(rate, now) < abs_diff(rate, best);
2308a6b7e2bSNikita Shubin }
2318a6b7e2bSNikita Shubin 
ep93xx_mux_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)2328a6b7e2bSNikita Shubin static int ep93xx_mux_determine_rate(struct clk_hw *hw,
2338a6b7e2bSNikita Shubin 				struct clk_rate_request *req)
2348a6b7e2bSNikita Shubin {
2358a6b7e2bSNikita Shubin 	unsigned long best_rate = 0, actual_rate, mclk_rate;
2368a6b7e2bSNikita Shubin 	unsigned long rate = req->rate;
2378a6b7e2bSNikita Shubin 	struct clk_hw *parent_best = NULL;
2388a6b7e2bSNikita Shubin 	unsigned long parent_rate_best;
2398a6b7e2bSNikita Shubin 	unsigned long parent_rate;
2408a6b7e2bSNikita Shubin 	int div, pdiv;
2418a6b7e2bSNikita Shubin 	unsigned int i;
2428a6b7e2bSNikita Shubin 
2438a6b7e2bSNikita Shubin 	/*
2448a6b7e2bSNikita Shubin 	 * Try the two pll's and the external clock,
2458a6b7e2bSNikita Shubin 	 * because the valid predividers are 2, 2.5 and 3, we multiply
2468a6b7e2bSNikita Shubin 	 * all the clocks by 2 to avoid floating point math.
2478a6b7e2bSNikita Shubin 	 *
2488a6b7e2bSNikita Shubin 	 * This is based on the algorithm in the ep93xx raster guide:
2498a6b7e2bSNikita Shubin 	 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
2508a6b7e2bSNikita Shubin 	 *
2518a6b7e2bSNikita Shubin 	 */
2528a6b7e2bSNikita Shubin 	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
2538a6b7e2bSNikita Shubin 		struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
2548a6b7e2bSNikita Shubin 
2558a6b7e2bSNikita Shubin 		parent_rate = clk_hw_get_rate(parent);
2568a6b7e2bSNikita Shubin 		mclk_rate = parent_rate * 2;
2578a6b7e2bSNikita Shubin 
2588a6b7e2bSNikita Shubin 		/* Try each predivider value */
2598a6b7e2bSNikita Shubin 		for (pdiv = 4; pdiv <= 6; pdiv++) {
2608a6b7e2bSNikita Shubin 			div = DIV_ROUND_CLOSEST(mclk_rate, rate * pdiv);
2618a6b7e2bSNikita Shubin 			if (!in_range(div, 1, 127))
2628a6b7e2bSNikita Shubin 				continue;
2638a6b7e2bSNikita Shubin 
2648a6b7e2bSNikita Shubin 			actual_rate = DIV_ROUND_CLOSEST(mclk_rate, pdiv * div);
2658a6b7e2bSNikita Shubin 			if (is_best(rate, actual_rate, best_rate)) {
2668a6b7e2bSNikita Shubin 				best_rate = actual_rate;
2678a6b7e2bSNikita Shubin 				parent_rate_best = parent_rate;
2688a6b7e2bSNikita Shubin 				parent_best = parent;
2698a6b7e2bSNikita Shubin 			}
2708a6b7e2bSNikita Shubin 		}
2718a6b7e2bSNikita Shubin 	}
2728a6b7e2bSNikita Shubin 
2738a6b7e2bSNikita Shubin 	if (!parent_best)
2748a6b7e2bSNikita Shubin 		return -EINVAL;
2758a6b7e2bSNikita Shubin 
2768a6b7e2bSNikita Shubin 	req->best_parent_rate = parent_rate_best;
2778a6b7e2bSNikita Shubin 	req->best_parent_hw = parent_best;
2788a6b7e2bSNikita Shubin 	req->rate = best_rate;
2798a6b7e2bSNikita Shubin 
2808a6b7e2bSNikita Shubin 	return 0;
2818a6b7e2bSNikita Shubin }
2828a6b7e2bSNikita Shubin 
ep93xx_ddiv_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)2838a6b7e2bSNikita Shubin static unsigned long ep93xx_ddiv_recalc_rate(struct clk_hw *hw,
2848a6b7e2bSNikita Shubin 						unsigned long parent_rate)
2858a6b7e2bSNikita Shubin {
2868a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
2878a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
2888a6b7e2bSNikita Shubin 	unsigned int pdiv, div;
2898a6b7e2bSNikita Shubin 	u32 val;
2908a6b7e2bSNikita Shubin 
2918a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
2928a6b7e2bSNikita Shubin 	pdiv = (val >> EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) & GENMASK(1, 0);
2938a6b7e2bSNikita Shubin 	div = val & GENMASK(6, 0);
2948a6b7e2bSNikita Shubin 	if (!div)
2958a6b7e2bSNikita Shubin 		return 0;
2968a6b7e2bSNikita Shubin 
2978a6b7e2bSNikita Shubin 	return DIV_ROUND_CLOSEST(parent_rate * 2, (pdiv + 3) * div);
2988a6b7e2bSNikita Shubin }
2998a6b7e2bSNikita Shubin 
ep93xx_ddiv_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)3008a6b7e2bSNikita Shubin static int ep93xx_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
3018a6b7e2bSNikita Shubin 				unsigned long parent_rate)
3028a6b7e2bSNikita Shubin {
3038a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
3048a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
3058a6b7e2bSNikita Shubin 	int pdiv, div, npdiv, ndiv;
3068a6b7e2bSNikita Shubin 	unsigned long actual_rate, mclk_rate, rate_err = ULONG_MAX;
3078a6b7e2bSNikita Shubin 	u32 val;
3088a6b7e2bSNikita Shubin 
3098a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
3108a6b7e2bSNikita Shubin 	mclk_rate = parent_rate * 2;
3118a6b7e2bSNikita Shubin 
3128a6b7e2bSNikita Shubin 	for (pdiv = 4; pdiv <= 6; pdiv++) {
3138a6b7e2bSNikita Shubin 		div = DIV_ROUND_CLOSEST(mclk_rate, rate * pdiv);
3148a6b7e2bSNikita Shubin 		if (!in_range(div, 1, 127))
3158a6b7e2bSNikita Shubin 			continue;
3168a6b7e2bSNikita Shubin 
3178a6b7e2bSNikita Shubin 		actual_rate = DIV_ROUND_CLOSEST(mclk_rate, pdiv * div);
3188a6b7e2bSNikita Shubin 		if (abs(actual_rate - rate) < rate_err) {
3198a6b7e2bSNikita Shubin 			npdiv = pdiv - 3;
3208a6b7e2bSNikita Shubin 			ndiv = div;
3218a6b7e2bSNikita Shubin 			rate_err = abs(actual_rate - rate);
3228a6b7e2bSNikita Shubin 		}
3238a6b7e2bSNikita Shubin 	}
3248a6b7e2bSNikita Shubin 
3258a6b7e2bSNikita Shubin 	if (rate_err == ULONG_MAX)
3268a6b7e2bSNikita Shubin 		return -EINVAL;
3278a6b7e2bSNikita Shubin 
3288a6b7e2bSNikita Shubin 	/*
3298a6b7e2bSNikita Shubin 	 * Clear old dividers.
3308a6b7e2bSNikita Shubin 	 * Bit 7 is reserved bit in all ClkDiv registers.
3318a6b7e2bSNikita Shubin 	 */
3328a6b7e2bSNikita Shubin 	val &= ~(GENMASK(9, 0) & ~BIT(7));
3338a6b7e2bSNikita Shubin 
3348a6b7e2bSNikita Shubin 	/* Set the new pdiv and div bits for the new clock rate */
3358a6b7e2bSNikita Shubin 	val |= (npdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | ndiv;
3368a6b7e2bSNikita Shubin 
3378a6b7e2bSNikita Shubin 	ep93xx_clk_write(priv, clk->reg, val);
3388a6b7e2bSNikita Shubin 
3398a6b7e2bSNikita Shubin 	return 0;
3408a6b7e2bSNikita Shubin }
3418a6b7e2bSNikita Shubin 
3428a6b7e2bSNikita Shubin static const struct clk_ops clk_ddiv_ops = {
3438a6b7e2bSNikita Shubin 	.enable = ep93xx_clk_enable,
3448a6b7e2bSNikita Shubin 	.disable = ep93xx_clk_disable,
3458a6b7e2bSNikita Shubin 	.is_enabled = ep93xx_clk_is_enabled,
3468a6b7e2bSNikita Shubin 	.get_parent = ep93xx_mux_get_parent,
3478a6b7e2bSNikita Shubin 	.set_parent = ep93xx_mux_set_parent_lock,
3488a6b7e2bSNikita Shubin 	.determine_rate = ep93xx_mux_determine_rate,
3498a6b7e2bSNikita Shubin 	.recalc_rate = ep93xx_ddiv_recalc_rate,
3508a6b7e2bSNikita Shubin 	.set_rate = ep93xx_ddiv_set_rate,
3518a6b7e2bSNikita Shubin };
3528a6b7e2bSNikita Shubin 
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)3538a6b7e2bSNikita Shubin static int ep93xx_clk_register_ddiv(struct ep93xx_clk *clk,
3548a6b7e2bSNikita Shubin 				const char *name,
3558a6b7e2bSNikita Shubin 				struct clk_parent_data *parent_data,
3568a6b7e2bSNikita Shubin 				u8 num_parents,
3578a6b7e2bSNikita Shubin 				unsigned int reg,
3588a6b7e2bSNikita Shubin 				u8 bit_idx)
3598a6b7e2bSNikita Shubin {
3608a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
3618a6b7e2bSNikita Shubin 	struct clk_init_data init = { };
3628a6b7e2bSNikita Shubin 
3638a6b7e2bSNikita Shubin 	init.name = name;
3648a6b7e2bSNikita Shubin 	init.ops = &clk_ddiv_ops;
3658a6b7e2bSNikita Shubin 	init.flags = 0;
3668a6b7e2bSNikita Shubin 	init.parent_data = parent_data;
3678a6b7e2bSNikita Shubin 	init.num_parents = num_parents;
3688a6b7e2bSNikita Shubin 
3698a6b7e2bSNikita Shubin 	clk->reg = reg;
3708a6b7e2bSNikita Shubin 	clk->bit_idx = bit_idx;
3718a6b7e2bSNikita Shubin 	clk->hw.init = &init;
3728a6b7e2bSNikita Shubin 
3738a6b7e2bSNikita Shubin 	return devm_clk_hw_register(priv->dev, &clk->hw);
3748a6b7e2bSNikita Shubin }
3758a6b7e2bSNikita Shubin 
ep93xx_div_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)3768a6b7e2bSNikita Shubin static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw,
3778a6b7e2bSNikita Shubin 					    unsigned long parent_rate)
3788a6b7e2bSNikita Shubin {
3798a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
3808a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
3818a6b7e2bSNikita Shubin 	u32 val;
3828a6b7e2bSNikita Shubin 	u8 index;
3838a6b7e2bSNikita Shubin 
3848a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
3858a6b7e2bSNikita Shubin 	index = (val & clk->mask) >> clk->shift;
386*53cf1dc4SDan Carpenter 	if (index >= clk->num_div)
3878a6b7e2bSNikita Shubin 		return 0;
3888a6b7e2bSNikita Shubin 
3898a6b7e2bSNikita Shubin 	return DIV_ROUND_CLOSEST(parent_rate, clk->div[index]);
3908a6b7e2bSNikita Shubin }
3918a6b7e2bSNikita Shubin 
ep93xx_div_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * parent_rate)3928a6b7e2bSNikita Shubin static long ep93xx_div_round_rate(struct clk_hw *hw, unsigned long rate,
3938a6b7e2bSNikita Shubin 				   unsigned long *parent_rate)
3948a6b7e2bSNikita Shubin {
3958a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
3968a6b7e2bSNikita Shubin 	unsigned long best = 0, now;
3978a6b7e2bSNikita Shubin 	unsigned int i;
3988a6b7e2bSNikita Shubin 
3998a6b7e2bSNikita Shubin 	for (i = 0; i < clk->num_div; i++) {
4008a6b7e2bSNikita Shubin 		if ((rate * clk->div[i]) == *parent_rate)
4018a6b7e2bSNikita Shubin 			return rate;
4028a6b7e2bSNikita Shubin 
4038a6b7e2bSNikita Shubin 		now = DIV_ROUND_CLOSEST(*parent_rate, clk->div[i]);
4048a6b7e2bSNikita Shubin 		if (!best || is_best(rate, now, best))
4058a6b7e2bSNikita Shubin 			best = now;
4068a6b7e2bSNikita Shubin 	}
4078a6b7e2bSNikita Shubin 
4088a6b7e2bSNikita Shubin 	return best;
4098a6b7e2bSNikita Shubin }
4108a6b7e2bSNikita Shubin 
ep93xx_div_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)4118a6b7e2bSNikita Shubin static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate,
4128a6b7e2bSNikita Shubin 			       unsigned long parent_rate)
4138a6b7e2bSNikita Shubin {
4148a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
4158a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
4168a6b7e2bSNikita Shubin 	unsigned int i;
4178a6b7e2bSNikita Shubin 	u32 val;
4188a6b7e2bSNikita Shubin 
4198a6b7e2bSNikita Shubin 	regmap_read(priv->map, clk->reg, &val);
4208a6b7e2bSNikita Shubin 	val &= ~clk->mask;
4218a6b7e2bSNikita Shubin 	for (i = 0; i < clk->num_div; i++)
4228a6b7e2bSNikita Shubin 		if (rate == DIV_ROUND_CLOSEST(parent_rate, clk->div[i]))
4238a6b7e2bSNikita Shubin 			break;
4248a6b7e2bSNikita Shubin 
4258a6b7e2bSNikita Shubin 	if (i == clk->num_div)
4268a6b7e2bSNikita Shubin 		return -EINVAL;
4278a6b7e2bSNikita Shubin 
4288a6b7e2bSNikita Shubin 	val |= i << clk->shift;
4298a6b7e2bSNikita Shubin 
4308a6b7e2bSNikita Shubin 	ep93xx_clk_write(priv, clk->reg, val);
4318a6b7e2bSNikita Shubin 
4328a6b7e2bSNikita Shubin 	return 0;
4338a6b7e2bSNikita Shubin }
4348a6b7e2bSNikita Shubin 
4358a6b7e2bSNikita Shubin static const struct clk_ops ep93xx_div_ops = {
4368a6b7e2bSNikita Shubin 	.enable = ep93xx_clk_enable,
4378a6b7e2bSNikita Shubin 	.disable = ep93xx_clk_disable,
4388a6b7e2bSNikita Shubin 	.is_enabled = ep93xx_clk_is_enabled,
4398a6b7e2bSNikita Shubin 	.recalc_rate = ep93xx_div_recalc_rate,
4408a6b7e2bSNikita Shubin 	.round_rate = ep93xx_div_round_rate,
4418a6b7e2bSNikita Shubin 	.set_rate = ep93xx_div_set_rate,
4428a6b7e2bSNikita Shubin };
4438a6b7e2bSNikita Shubin 
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)4448a6b7e2bSNikita Shubin static int ep93xx_register_div(struct ep93xx_clk *clk,
4458a6b7e2bSNikita Shubin 			       const char *name,
4468a6b7e2bSNikita Shubin 			       const struct clk_parent_data *parent_data,
4478a6b7e2bSNikita Shubin 			       unsigned int reg,
4488a6b7e2bSNikita Shubin 			       u8 enable_bit,
4498a6b7e2bSNikita Shubin 			       u8 shift,
4508a6b7e2bSNikita Shubin 			       u8 width,
4518a6b7e2bSNikita Shubin 			       const char *clk_divisors,
4528a6b7e2bSNikita Shubin 			       u8 num_div)
4538a6b7e2bSNikita Shubin {
4548a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
4558a6b7e2bSNikita Shubin 	struct clk_init_data init = { };
4568a6b7e2bSNikita Shubin 
4578a6b7e2bSNikita Shubin 	init.name = name;
4588a6b7e2bSNikita Shubin 	init.ops = &ep93xx_div_ops;
4598a6b7e2bSNikita Shubin 	init.flags = 0;
4608a6b7e2bSNikita Shubin 	init.parent_data = parent_data;
4618a6b7e2bSNikita Shubin 	init.num_parents = 1;
4628a6b7e2bSNikita Shubin 
4638a6b7e2bSNikita Shubin 	clk->reg = reg;
4648a6b7e2bSNikita Shubin 	clk->bit_idx = enable_bit;
4658a6b7e2bSNikita Shubin 	clk->mask = GENMASK(shift + width - 1, shift);
4668a6b7e2bSNikita Shubin 	clk->shift = shift;
4678a6b7e2bSNikita Shubin 	clk->div = clk_divisors;
4688a6b7e2bSNikita Shubin 	clk->num_div = num_div;
4698a6b7e2bSNikita Shubin 	clk->hw.init = &init;
4708a6b7e2bSNikita Shubin 
4718a6b7e2bSNikita Shubin 	return devm_clk_hw_register(priv->dev, &clk->hw);
4728a6b7e2bSNikita Shubin }
4738a6b7e2bSNikita Shubin 
4748a6b7e2bSNikita Shubin struct ep93xx_gate {
4758a6b7e2bSNikita Shubin 	unsigned int idx;
4768a6b7e2bSNikita Shubin 	unsigned int bit;
4778a6b7e2bSNikita Shubin 	const char *name;
4788a6b7e2bSNikita Shubin };
4798a6b7e2bSNikita Shubin 
4808a6b7e2bSNikita Shubin static const struct ep93xx_gate ep93xx_uarts[] = {
4818a6b7e2bSNikita Shubin 	{ EP93XX_CLK_UART1, EP93XX_SYSCON_DEVCFG_U1EN, "uart1" },
4828a6b7e2bSNikita Shubin 	{ EP93XX_CLK_UART2, EP93XX_SYSCON_DEVCFG_U2EN, "uart2" },
4838a6b7e2bSNikita Shubin 	{ EP93XX_CLK_UART3, EP93XX_SYSCON_DEVCFG_U3EN, "uart3" },
4848a6b7e2bSNikita Shubin };
4858a6b7e2bSNikita Shubin 
ep93xx_uart_clock_init(struct ep93xx_clk_priv * priv)4868a6b7e2bSNikita Shubin static int ep93xx_uart_clock_init(struct ep93xx_clk_priv *priv)
4878a6b7e2bSNikita Shubin {
4888a6b7e2bSNikita Shubin 	struct clk_parent_data parent_data = { };
4898a6b7e2bSNikita Shubin 	unsigned int i, idx, ret, clk_uart_div;
4908a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk;
4918a6b7e2bSNikita Shubin 	u32 val;
4928a6b7e2bSNikita Shubin 
4938a6b7e2bSNikita Shubin 	regmap_read(priv->map, EP93XX_SYSCON_PWRCNT, &val);
4948a6b7e2bSNikita Shubin 	if (val & EP93XX_SYSCON_PWRCNT_UARTBAUD)
4958a6b7e2bSNikita Shubin 		clk_uart_div = 1;
4968a6b7e2bSNikita Shubin 	else
4978a6b7e2bSNikita Shubin 		clk_uart_div = 2;
4988a6b7e2bSNikita Shubin 
4998a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_UART] =
5008a6b7e2bSNikita Shubin 		devm_clk_hw_register_fixed_factor_index(priv->dev, "uart",
5018a6b7e2bSNikita Shubin 							0, /* XTALI external clock */
5028a6b7e2bSNikita Shubin 							0, 1, clk_uart_div);
5038a6b7e2bSNikita Shubin 	parent_data.hw = priv->fixed[EP93XX_CLK_UART];
5048a6b7e2bSNikita Shubin 
5058a6b7e2bSNikita Shubin 	/* parenting uart gate clocks to uart clock */
5068a6b7e2bSNikita Shubin 	for (i = 0; i < ARRAY_SIZE(ep93xx_uarts); i++) {
5078a6b7e2bSNikita Shubin 		idx = ep93xx_uarts[i].idx - EP93XX_CLK_UART1;
5088a6b7e2bSNikita Shubin 		clk = &priv->reg[idx];
5098a6b7e2bSNikita Shubin 		clk->idx = idx;
5108a6b7e2bSNikita Shubin 		ret = ep93xx_clk_register_gate(clk,
5118a6b7e2bSNikita Shubin 					ep93xx_uarts[i].name,
5128a6b7e2bSNikita Shubin 					&parent_data, CLK_SET_RATE_PARENT,
5138a6b7e2bSNikita Shubin 					EP93XX_SYSCON_DEVCFG,
5148a6b7e2bSNikita Shubin 					ep93xx_uarts[i].bit);
5158a6b7e2bSNikita Shubin 		if (ret)
5168a6b7e2bSNikita Shubin 			return dev_err_probe(priv->dev, ret,
5178a6b7e2bSNikita Shubin 					     "failed to register uart[%d] clock\n", i);
5188a6b7e2bSNikita Shubin 	}
5198a6b7e2bSNikita Shubin 
5208a6b7e2bSNikita Shubin 	return 0;
5218a6b7e2bSNikita Shubin }
5228a6b7e2bSNikita Shubin 
5238a6b7e2bSNikita Shubin static const struct ep93xx_gate ep93xx_dmas[] = {
5248a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2M0, EP93XX_SYSCON_PWRCNT_DMA_M2M0, "m2m0" },
5258a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2M1, EP93XX_SYSCON_PWRCNT_DMA_M2M1, "m2m1" },
5268a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P0, EP93XX_SYSCON_PWRCNT_DMA_M2P0, "m2p0" },
5278a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P1, EP93XX_SYSCON_PWRCNT_DMA_M2P1, "m2p1" },
5288a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P2, EP93XX_SYSCON_PWRCNT_DMA_M2P2, "m2p2" },
5298a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P3, EP93XX_SYSCON_PWRCNT_DMA_M2P3, "m2p3" },
5308a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P4, EP93XX_SYSCON_PWRCNT_DMA_M2P4, "m2p4" },
5318a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P5, EP93XX_SYSCON_PWRCNT_DMA_M2P5, "m2p5" },
5328a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P6, EP93XX_SYSCON_PWRCNT_DMA_M2P6, "m2p6" },
5338a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P7, EP93XX_SYSCON_PWRCNT_DMA_M2P7, "m2p7" },
5348a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P8, EP93XX_SYSCON_PWRCNT_DMA_M2P8, "m2p8" },
5358a6b7e2bSNikita Shubin 	{ EP93XX_CLK_M2P9, EP93XX_SYSCON_PWRCNT_DMA_M2P9, "m2p9" },
5368a6b7e2bSNikita Shubin };
5378a6b7e2bSNikita Shubin 
ep93xx_dma_clock_init(struct ep93xx_clk_priv * priv)5388a6b7e2bSNikita Shubin static int ep93xx_dma_clock_init(struct ep93xx_clk_priv *priv)
5398a6b7e2bSNikita Shubin {
5408a6b7e2bSNikita Shubin 	struct clk_parent_data parent_data = { };
5418a6b7e2bSNikita Shubin 	unsigned int i, idx;
5428a6b7e2bSNikita Shubin 
5438a6b7e2bSNikita Shubin 	parent_data.hw = priv->fixed[EP93XX_CLK_HCLK];
5448a6b7e2bSNikita Shubin 	for (i = 0; i < ARRAY_SIZE(ep93xx_dmas); i++) {
5458a6b7e2bSNikita Shubin 		idx = ep93xx_dmas[i].idx;
5468a6b7e2bSNikita Shubin 		priv->fixed[idx] = devm_clk_hw_register_gate_parent_data(priv->dev,
5478a6b7e2bSNikita Shubin 					ep93xx_dmas[i].name,
5488a6b7e2bSNikita Shubin 					&parent_data, 0,
5498a6b7e2bSNikita Shubin 					priv->base + EP93XX_SYSCON_PWRCNT,
5508a6b7e2bSNikita Shubin 					ep93xx_dmas[i].bit,
5518a6b7e2bSNikita Shubin 					0,
5528a6b7e2bSNikita Shubin 					&priv->lock);
5538a6b7e2bSNikita Shubin 		if (IS_ERR(priv->fixed[idx]))
5548a6b7e2bSNikita Shubin 			return PTR_ERR(priv->fixed[idx]);
5558a6b7e2bSNikita Shubin 	}
5568a6b7e2bSNikita Shubin 
5578a6b7e2bSNikita Shubin 	return 0;
5588a6b7e2bSNikita Shubin }
5598a6b7e2bSNikita Shubin 
of_clk_ep93xx_get(struct of_phandle_args * clkspec,void * data)5608a6b7e2bSNikita Shubin static struct clk_hw *of_clk_ep93xx_get(struct of_phandle_args *clkspec, void *data)
5618a6b7e2bSNikita Shubin {
5628a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv = data;
5638a6b7e2bSNikita Shubin 	unsigned int idx = clkspec->args[0];
5648a6b7e2bSNikita Shubin 
5658a6b7e2bSNikita Shubin 	if (idx < EP93XX_CLK_UART1)
5668a6b7e2bSNikita Shubin 		return priv->fixed[idx];
5678a6b7e2bSNikita Shubin 
5688a6b7e2bSNikita Shubin 	if (idx <= EP93XX_CLK_I2S_LRCLK)
5698a6b7e2bSNikita Shubin 		return &priv->reg[idx - EP93XX_CLK_UART1].hw;
5708a6b7e2bSNikita Shubin 
5718a6b7e2bSNikita Shubin 	return ERR_PTR(-EINVAL);
5728a6b7e2bSNikita Shubin }
5738a6b7e2bSNikita Shubin 
5748a6b7e2bSNikita Shubin /*
5758a6b7e2bSNikita Shubin  * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
5768a6b7e2bSNikita Shubin  */
calc_pll_rate(u64 rate,u32 config_word)5778a6b7e2bSNikita Shubin static unsigned long calc_pll_rate(u64 rate, u32 config_word)
5788a6b7e2bSNikita Shubin {
5798a6b7e2bSNikita Shubin 	rate *= ((config_word >> 11) & GENMASK(4, 0)) + 1;	/* X1FBD */
5808a6b7e2bSNikita Shubin 	rate *= ((config_word >> 5) & GENMASK(5, 0)) + 1;	/* X2FBD */
5818a6b7e2bSNikita Shubin 	do_div(rate, (config_word & GENMASK(4, 0)) + 1);	/* X2IPD */
5828a6b7e2bSNikita Shubin 	rate >>= (config_word >> 16) & GENMASK(1, 0);		/* PS */
5838a6b7e2bSNikita Shubin 
5848a6b7e2bSNikita Shubin 	return rate;
5858a6b7e2bSNikita Shubin }
5868a6b7e2bSNikita Shubin 
ep93xx_plls_init(struct ep93xx_clk_priv * priv)5878a6b7e2bSNikita Shubin static int ep93xx_plls_init(struct ep93xx_clk_priv *priv)
5888a6b7e2bSNikita Shubin {
5898a6b7e2bSNikita Shubin 	const char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
5908a6b7e2bSNikita Shubin 	const char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
5918a6b7e2bSNikita Shubin 	const char pclk_divisors[] = { 1, 2, 4, 8 };
5928a6b7e2bSNikita Shubin 	struct clk_parent_data xtali = { .index = 0 };
5938a6b7e2bSNikita Shubin 	unsigned int clk_f_div, clk_h_div, clk_p_div;
5948a6b7e2bSNikita Shubin 	unsigned long clk_pll1_rate, clk_pll2_rate;
5958a6b7e2bSNikita Shubin 	struct device *dev = priv->dev;
5968a6b7e2bSNikita Shubin 	struct clk_hw *hw, *pll1;
5978a6b7e2bSNikita Shubin 	u32 value;
5988a6b7e2bSNikita Shubin 
5998a6b7e2bSNikita Shubin 	/* Determine the bootloader configured pll1 rate */
6008a6b7e2bSNikita Shubin 	regmap_read(priv->map, EP93XX_SYSCON_CLKSET1, &value);
6018a6b7e2bSNikita Shubin 
6028a6b7e2bSNikita Shubin 	if (value & EP93XX_SYSCON_CLKSET1_NBYP1)
6038a6b7e2bSNikita Shubin 		clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
6048a6b7e2bSNikita Shubin 	else
6058a6b7e2bSNikita Shubin 		clk_pll1_rate = EP93XX_EXT_CLK_RATE;
6068a6b7e2bSNikita Shubin 
6078a6b7e2bSNikita Shubin 	pll1 = devm_clk_hw_register_fixed_rate_parent_data(dev, "pll1", &xtali,
6088a6b7e2bSNikita Shubin 								  0, clk_pll1_rate);
6098a6b7e2bSNikita Shubin 	if (IS_ERR(pll1))
6108a6b7e2bSNikita Shubin 		return PTR_ERR(pll1);
6118a6b7e2bSNikita Shubin 
6128a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_PLL1] = pll1;
6138a6b7e2bSNikita Shubin 
6148a6b7e2bSNikita Shubin 	/* Initialize the pll1 derived clocks */
6158a6b7e2bSNikita Shubin 	clk_f_div = fclk_divisors[(value >> 25) & GENMASK(2, 0)];
6168a6b7e2bSNikita Shubin 	clk_h_div = hclk_divisors[(value >> 20) & GENMASK(2, 0)];
6178a6b7e2bSNikita Shubin 	clk_p_div = pclk_divisors[(value >> 18) & GENMASK(1, 0)];
6188a6b7e2bSNikita Shubin 
6198a6b7e2bSNikita Shubin 	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "fclk", pll1, 0, 1, clk_f_div);
6208a6b7e2bSNikita Shubin 	if (IS_ERR(hw))
6218a6b7e2bSNikita Shubin 		return PTR_ERR(hw);
6228a6b7e2bSNikita Shubin 
6238a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_FCLK] = hw;
6248a6b7e2bSNikita Shubin 
6258a6b7e2bSNikita Shubin 	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "hclk", pll1, 0, 1, clk_h_div);
6268a6b7e2bSNikita Shubin 	if (IS_ERR(hw))
6278a6b7e2bSNikita Shubin 		return PTR_ERR(hw);
6288a6b7e2bSNikita Shubin 
6298a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_HCLK] = hw;
6308a6b7e2bSNikita Shubin 
6318a6b7e2bSNikita Shubin 	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "pclk", hw, 0, 1, clk_p_div);
6328a6b7e2bSNikita Shubin 	if (IS_ERR(hw))
6338a6b7e2bSNikita Shubin 		return PTR_ERR(hw);
6348a6b7e2bSNikita Shubin 
6358a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_PCLK] = hw;
6368a6b7e2bSNikita Shubin 
6378a6b7e2bSNikita Shubin 	/* Determine the bootloader configured pll2 rate */
6388a6b7e2bSNikita Shubin 	regmap_read(priv->map, EP93XX_SYSCON_CLKSET2, &value);
6398a6b7e2bSNikita Shubin 	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
6408a6b7e2bSNikita Shubin 		clk_pll2_rate = EP93XX_EXT_CLK_RATE;
6418a6b7e2bSNikita Shubin 	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
6428a6b7e2bSNikita Shubin 		clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
6438a6b7e2bSNikita Shubin 	else
6448a6b7e2bSNikita Shubin 		clk_pll2_rate = 0;
6458a6b7e2bSNikita Shubin 
6468a6b7e2bSNikita Shubin 	hw = devm_clk_hw_register_fixed_rate_parent_data(dev, "pll2", &xtali,
6478a6b7e2bSNikita Shubin 								0, clk_pll2_rate);
6488a6b7e2bSNikita Shubin 	if (IS_ERR(hw))
6498a6b7e2bSNikita Shubin 		return PTR_ERR(hw);
6508a6b7e2bSNikita Shubin 
6518a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_PLL2] = hw;
6528a6b7e2bSNikita Shubin 
6538a6b7e2bSNikita Shubin 	return 0;
6548a6b7e2bSNikita Shubin }
6558a6b7e2bSNikita Shubin 
ep93xx_clk_probe(struct auxiliary_device * adev,const struct auxiliary_device_id * id)6568a6b7e2bSNikita Shubin static int ep93xx_clk_probe(struct auxiliary_device *adev,
6578a6b7e2bSNikita Shubin 			       const struct auxiliary_device_id *id)
6588a6b7e2bSNikita Shubin {
6598a6b7e2bSNikita Shubin 	struct ep93xx_regmap_adev *rdev = to_ep93xx_regmap_adev(adev);
6608a6b7e2bSNikita Shubin 	struct clk_parent_data xtali = { .index = 0 };
6618a6b7e2bSNikita Shubin 	struct clk_parent_data ddiv_pdata[3] = { };
6628a6b7e2bSNikita Shubin 	unsigned int clk_spi_div, clk_usb_div;
6638a6b7e2bSNikita Shubin 	struct clk_parent_data pdata = {};
6648a6b7e2bSNikita Shubin 	struct device *dev = &adev->dev;
6658a6b7e2bSNikita Shubin 	struct ep93xx_clk_priv *priv;
6668a6b7e2bSNikita Shubin 	struct ep93xx_clk *clk;
6678a6b7e2bSNikita Shubin 	struct clk_hw *hw;
6688a6b7e2bSNikita Shubin 	unsigned int idx;
6698a6b7e2bSNikita Shubin 	int ret;
6708a6b7e2bSNikita Shubin 	u32 value;
6718a6b7e2bSNikita Shubin 
6728a6b7e2bSNikita Shubin 	priv = devm_kzalloc(dev, struct_size(priv, reg, 10), GFP_KERNEL);
6738a6b7e2bSNikita Shubin 	if (!priv)
6748a6b7e2bSNikita Shubin 		return -ENOMEM;
6758a6b7e2bSNikita Shubin 
6768a6b7e2bSNikita Shubin 	spin_lock_init(&priv->lock);
6778a6b7e2bSNikita Shubin 	priv->dev = dev;
6788a6b7e2bSNikita Shubin 	priv->aux_dev = rdev;
6798a6b7e2bSNikita Shubin 	priv->map = rdev->map;
6808a6b7e2bSNikita Shubin 	priv->base = rdev->base;
6818a6b7e2bSNikita Shubin 
6828a6b7e2bSNikita Shubin 	ret = ep93xx_plls_init(priv);
6838a6b7e2bSNikita Shubin 	if (ret)
6848a6b7e2bSNikita Shubin 		return ret;
6858a6b7e2bSNikita Shubin 
6868a6b7e2bSNikita Shubin 	regmap_read(priv->map, EP93XX_SYSCON_CLKSET2, &value);
6878a6b7e2bSNikita Shubin 	clk_usb_div = (value >> 28 & GENMASK(3, 0)) + 1;
6888a6b7e2bSNikita Shubin 	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "usb_clk",
6898a6b7e2bSNikita Shubin 							 priv->fixed[EP93XX_CLK_PLL2], 0, 1,
6908a6b7e2bSNikita Shubin 							 clk_usb_div);
6918a6b7e2bSNikita Shubin 	if (IS_ERR(hw))
6928a6b7e2bSNikita Shubin 		return PTR_ERR(hw);
6938a6b7e2bSNikita Shubin 
6948a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_USB] = hw;
6958a6b7e2bSNikita Shubin 
6968a6b7e2bSNikita Shubin 	ret = ep93xx_uart_clock_init(priv);
6978a6b7e2bSNikita Shubin 	if (ret)
6988a6b7e2bSNikita Shubin 		return ret;
6998a6b7e2bSNikita Shubin 
7008a6b7e2bSNikita Shubin 	ret = ep93xx_dma_clock_init(priv);
7018a6b7e2bSNikita Shubin 	if (ret)
7028a6b7e2bSNikita Shubin 		return ret;
7038a6b7e2bSNikita Shubin 
7048a6b7e2bSNikita Shubin 	clk_spi_div = id->driver_data;
7058a6b7e2bSNikita Shubin 	hw = devm_clk_hw_register_fixed_factor_index(dev, "ep93xx-spi.0",
7068a6b7e2bSNikita Shubin 						     0, /* XTALI external clock */
7078a6b7e2bSNikita Shubin 						     0, 1, clk_spi_div);
7088a6b7e2bSNikita Shubin 	if (IS_ERR(hw))
7098a6b7e2bSNikita Shubin 		return PTR_ERR(hw);
7108a6b7e2bSNikita Shubin 
7118a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_SPI] = hw;
7128a6b7e2bSNikita Shubin 
7138a6b7e2bSNikita Shubin 	/* PWM clock */
7148a6b7e2bSNikita Shubin 	hw = devm_clk_hw_register_fixed_factor_index(dev, "pwm_clk", 0, /* XTALI external clock */
7158a6b7e2bSNikita Shubin 						     0, 1, 1);
7168a6b7e2bSNikita Shubin 	if (IS_ERR(hw))
7178a6b7e2bSNikita Shubin 		return PTR_ERR(hw);
7188a6b7e2bSNikita Shubin 
7198a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_PWM] = hw;
7208a6b7e2bSNikita Shubin 
7218a6b7e2bSNikita Shubin 	/* USB clock */
7228a6b7e2bSNikita Shubin 	pdata.hw = priv->fixed[EP93XX_CLK_USB];
7238a6b7e2bSNikita Shubin 	hw = devm_clk_hw_register_gate_parent_data(priv->dev, "ohci-platform", &pdata,
7248a6b7e2bSNikita Shubin 						   0, priv->base + EP93XX_SYSCON_PWRCNT,
7258a6b7e2bSNikita Shubin 						   EP93XX_SYSCON_PWRCNT_USH_EN, 0,
7268a6b7e2bSNikita Shubin 						   &priv->lock);
7278a6b7e2bSNikita Shubin 	if (IS_ERR(hw))
7288a6b7e2bSNikita Shubin 		return PTR_ERR(hw);
7298a6b7e2bSNikita Shubin 
7308a6b7e2bSNikita Shubin 	priv->fixed[EP93XX_CLK_USB] = hw;
7318a6b7e2bSNikita Shubin 
7328a6b7e2bSNikita Shubin 	ddiv_pdata[0].index = 0; /* XTALI external clock */
7338a6b7e2bSNikita Shubin 	ddiv_pdata[1].hw = priv->fixed[EP93XX_CLK_PLL1];
7348a6b7e2bSNikita Shubin 	ddiv_pdata[2].hw = priv->fixed[EP93XX_CLK_PLL2];
7358a6b7e2bSNikita Shubin 
7368a6b7e2bSNikita Shubin 	/* touchscreen/ADC clock */
7378a6b7e2bSNikita Shubin 	idx = EP93XX_CLK_ADC - EP93XX_CLK_UART1;
7388a6b7e2bSNikita Shubin 	clk = &priv->reg[idx];
7398a6b7e2bSNikita Shubin 	clk->idx = idx;
7408a6b7e2bSNikita Shubin 	ret = ep93xx_register_div(clk, "ep93xx-adc", &xtali,
7418a6b7e2bSNikita Shubin 				EP93XX_SYSCON_KEYTCHCLKDIV,
7428a6b7e2bSNikita Shubin 				EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
7438a6b7e2bSNikita Shubin 				EP93XX_SYSCON_KEYTCHCLKDIV_ADIV,
7448a6b7e2bSNikita Shubin 				1,
7458a6b7e2bSNikita Shubin 				ep93xx_adc_divisors,
7468a6b7e2bSNikita Shubin 				ARRAY_SIZE(ep93xx_adc_divisors));
7478a6b7e2bSNikita Shubin 
7488a6b7e2bSNikita Shubin 
7498a6b7e2bSNikita Shubin 	/* keypad clock */
7508a6b7e2bSNikita Shubin 	idx = EP93XX_CLK_KEYPAD - EP93XX_CLK_UART1;
7518a6b7e2bSNikita Shubin 	clk = &priv->reg[idx];
7528a6b7e2bSNikita Shubin 	clk->idx = idx;
7538a6b7e2bSNikita Shubin 	ret = ep93xx_register_div(clk, "ep93xx-keypad", &xtali,
7548a6b7e2bSNikita Shubin 				EP93XX_SYSCON_KEYTCHCLKDIV,
7558a6b7e2bSNikita Shubin 				EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
7568a6b7e2bSNikita Shubin 				EP93XX_SYSCON_KEYTCHCLKDIV_KDIV,
7578a6b7e2bSNikita Shubin 				1,
7588a6b7e2bSNikita Shubin 				ep93xx_adc_divisors,
7598a6b7e2bSNikita Shubin 				ARRAY_SIZE(ep93xx_adc_divisors));
7608a6b7e2bSNikita Shubin 
7618a6b7e2bSNikita Shubin 	/*
7628a6b7e2bSNikita Shubin 	 * On reset PDIV and VDIV is set to zero, while PDIV zero
7638a6b7e2bSNikita Shubin 	 * means clock disable, VDIV shouldn't be zero.
7648a6b7e2bSNikita Shubin 	 * So we set both video and i2s dividers to minimum.
7658a6b7e2bSNikita Shubin 	 * ENA - Enable CLK divider.
7668a6b7e2bSNikita Shubin 	 * PDIV - 00 - Disable clock
7678a6b7e2bSNikita Shubin 	 * VDIV - at least 2
7688a6b7e2bSNikita Shubin 	 */
7698a6b7e2bSNikita Shubin 
7708a6b7e2bSNikita Shubin 	/* Check and enable video clk registers */
7718a6b7e2bSNikita Shubin 	regmap_read(priv->map, EP93XX_SYSCON_VIDCLKDIV, &value);
7728a6b7e2bSNikita Shubin 	value |= BIT(EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
7738a6b7e2bSNikita Shubin 	ep93xx_clk_write(priv, EP93XX_SYSCON_VIDCLKDIV, value);
7748a6b7e2bSNikita Shubin 
7758a6b7e2bSNikita Shubin 	/* Check and enable i2s clk registers */
7768a6b7e2bSNikita Shubin 	regmap_read(priv->map, EP93XX_SYSCON_I2SCLKDIV, &value);
7778a6b7e2bSNikita Shubin 	value |= BIT(EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
7788a6b7e2bSNikita Shubin 
7798a6b7e2bSNikita Shubin 	/*
7808a6b7e2bSNikita Shubin 	 * Override the SAI_MSTR_CLK_CFG from the I2S block and use the
7818a6b7e2bSNikita Shubin 	 * I2SClkDiv Register settings. LRCLK transitions on the falling SCLK
7828a6b7e2bSNikita Shubin 	 * edge.
7838a6b7e2bSNikita Shubin 	 */
7848a6b7e2bSNikita Shubin 	value |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
7858a6b7e2bSNikita Shubin 	ep93xx_clk_write(priv, EP93XX_SYSCON_I2SCLKDIV, value);
7868a6b7e2bSNikita Shubin 
7878a6b7e2bSNikita Shubin 	/* video clk */
7888a6b7e2bSNikita Shubin 	idx = EP93XX_CLK_VIDEO - EP93XX_CLK_UART1;
7898a6b7e2bSNikita Shubin 	clk = &priv->reg[idx];
7908a6b7e2bSNikita Shubin 	clk->idx = idx;
7918a6b7e2bSNikita Shubin 	ret = ep93xx_clk_register_ddiv(clk, "ep93xx-fb",
7928a6b7e2bSNikita Shubin 				ddiv_pdata, ARRAY_SIZE(ddiv_pdata),
7938a6b7e2bSNikita Shubin 				EP93XX_SYSCON_VIDCLKDIV,
7948a6b7e2bSNikita Shubin 				EP93XX_SYSCON_CLKDIV_ENABLE);
7958a6b7e2bSNikita Shubin 
7968a6b7e2bSNikita Shubin 	/* i2s clk */
7978a6b7e2bSNikita Shubin 	idx = EP93XX_CLK_I2S_MCLK - EP93XX_CLK_UART1;
7988a6b7e2bSNikita Shubin 	clk = &priv->reg[idx];
7998a6b7e2bSNikita Shubin 	clk->idx = idx;
8008a6b7e2bSNikita Shubin 	ret = ep93xx_clk_register_ddiv(clk, "mclk",
8018a6b7e2bSNikita Shubin 				ddiv_pdata, ARRAY_SIZE(ddiv_pdata),
8028a6b7e2bSNikita Shubin 				EP93XX_SYSCON_I2SCLKDIV,
8038a6b7e2bSNikita Shubin 				EP93XX_SYSCON_CLKDIV_ENABLE);
8048a6b7e2bSNikita Shubin 
8058a6b7e2bSNikita Shubin 	/* i2s sclk */
8068a6b7e2bSNikita Shubin 	idx = EP93XX_CLK_I2S_SCLK - EP93XX_CLK_UART1;
8078a6b7e2bSNikita Shubin 	clk = &priv->reg[idx];
8088a6b7e2bSNikita Shubin 	clk->idx = idx;
8098a6b7e2bSNikita Shubin 	pdata.hw = &priv->reg[EP93XX_CLK_I2S_MCLK - EP93XX_CLK_UART1].hw;
8108a6b7e2bSNikita Shubin 	ret = ep93xx_register_div(clk, "sclk", &pdata,
8118a6b7e2bSNikita Shubin 				EP93XX_SYSCON_I2SCLKDIV,
8128a6b7e2bSNikita Shubin 				EP93XX_SYSCON_I2SCLKDIV_SENA,
8138a6b7e2bSNikita Shubin 				16, /* EP93XX_I2SCLKDIV_SDIV_SHIFT */
8148a6b7e2bSNikita Shubin 				1,  /* EP93XX_I2SCLKDIV_SDIV_WIDTH */
8158a6b7e2bSNikita Shubin 				ep93xx_sclk_divisors,
8168a6b7e2bSNikita Shubin 				ARRAY_SIZE(ep93xx_sclk_divisors));
8178a6b7e2bSNikita Shubin 
8188a6b7e2bSNikita Shubin 	/* i2s lrclk */
8198a6b7e2bSNikita Shubin 	idx = EP93XX_CLK_I2S_LRCLK - EP93XX_CLK_UART1;
8208a6b7e2bSNikita Shubin 	clk = &priv->reg[idx];
8218a6b7e2bSNikita Shubin 	clk->idx = idx;
8228a6b7e2bSNikita Shubin 	pdata.hw = &priv->reg[EP93XX_CLK_I2S_SCLK - EP93XX_CLK_UART1].hw;
8238a6b7e2bSNikita Shubin 	ret = ep93xx_register_div(clk, "lrclk", &pdata,
8248a6b7e2bSNikita Shubin 				EP93XX_SYSCON_I2SCLKDIV,
8258a6b7e2bSNikita Shubin 				EP93XX_SYSCON_I2SCLKDIV_SENA,
8268a6b7e2bSNikita Shubin 				17, /* EP93XX_I2SCLKDIV_LRDIV32_SHIFT */
8278a6b7e2bSNikita Shubin 				2,  /* EP93XX_I2SCLKDIV_LRDIV32_WIDTH */
8288a6b7e2bSNikita Shubin 				ep93xx_lrclk_divisors,
8298a6b7e2bSNikita Shubin 				ARRAY_SIZE(ep93xx_lrclk_divisors));
8308a6b7e2bSNikita Shubin 
8318a6b7e2bSNikita Shubin 	/* IrDa clk uses same pattern but no init code presents in original clock driver */
8328a6b7e2bSNikita Shubin 	return devm_of_clk_add_hw_provider(priv->dev, of_clk_ep93xx_get, priv);
8338a6b7e2bSNikita Shubin }
8348a6b7e2bSNikita Shubin 
8358a6b7e2bSNikita Shubin static const struct auxiliary_device_id ep93xx_clk_ids[] = {
8368a6b7e2bSNikita Shubin 	{ .name = "soc_ep93xx.clk-ep93xx", .driver_data = 2, },
8378a6b7e2bSNikita Shubin 	{ .name = "soc_ep93xx.clk-ep93xx.e2", .driver_data = 1, },
8388a6b7e2bSNikita Shubin 	{ /* sentinel */ }
8398a6b7e2bSNikita Shubin };
8408a6b7e2bSNikita Shubin MODULE_DEVICE_TABLE(auxiliary, ep93xx_clk_ids);
8418a6b7e2bSNikita Shubin 
8428a6b7e2bSNikita Shubin static struct auxiliary_driver ep93xx_clk_driver = {
8438a6b7e2bSNikita Shubin 	.probe		= ep93xx_clk_probe,
8448a6b7e2bSNikita Shubin 	.id_table	= ep93xx_clk_ids,
8458a6b7e2bSNikita Shubin };
8468a6b7e2bSNikita Shubin module_auxiliary_driver(ep93xx_clk_driver);
847e2a79105SArnd Bergmann 
848e2a79105SArnd Bergmann MODULE_LICENSE("GPL");
849e2a79105SArnd Bergmann MODULE_AUTHOR("Nikita Shubin <nikita.shubin@maquefel.me>");
850e2a79105SArnd Bergmann MODULE_DESCRIPTION("Clock control for Cirrus EP93xx chips");
851