1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2017-2019 NXP.
4  *
5  * Peng Fan <peng.fan@nxp.com>
6  */
7 
8 #include <common.h>
9 #include <asm/io.h>
10 #include <malloc.h>
11 #include <clk-uclass.h>
12 #include <dm/device.h>
13 #include <dm/devres.h>
14 #include <linux/bitops.h>
15 #include <linux/clk-provider.h>
16 #include <linux/delay.h>
17 #include <linux/err.h>
18 #include <linux/iopoll.h>
19 #include <clk.h>
20 #include <div64.h>
21 
22 #include "clk.h"
23 
24 #define UBOOT_DM_CLK_IMX_PLL1443X "imx_clk_pll1443x"
25 #define UBOOT_DM_CLK_IMX_PLL1416X "imx_clk_pll1416x"
26 
27 #define GNRL_CTL	0x0
28 #define DIV_CTL		0x4
29 #define LOCK_STATUS	BIT(31)
30 #define LOCK_SEL_MASK	BIT(29)
31 #define CLKE_MASK	BIT(11)
32 #define RST_MASK	BIT(9)
33 #define BYPASS_MASK	BIT(4)
34 #define MDIV_SHIFT	12
35 #define MDIV_MASK	GENMASK(21, 12)
36 #define PDIV_SHIFT	4
37 #define PDIV_MASK	GENMASK(9, 4)
38 #define SDIV_SHIFT	0
39 #define SDIV_MASK	GENMASK(2, 0)
40 #define KDIV_SHIFT	0
41 #define KDIV_MASK	GENMASK(15, 0)
42 
43 #define LOCK_TIMEOUT_US		10000
44 
45 struct clk_pll14xx {
46 	struct clk			clk;
47 	void __iomem			*base;
48 	enum imx_pll14xx_type		type;
49 	const struct imx_pll14xx_rate_table *rate_table;
50 	int rate_count;
51 };
52 
53 #define to_clk_pll14xx(_clk) container_of(_clk, struct clk_pll14xx, clk)
54 
imx_get_pll_settings(struct clk_pll14xx * pll,unsigned long rate)55 static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
56 		struct clk_pll14xx *pll, unsigned long rate)
57 {
58 	const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
59 	int i;
60 
61 	for (i = 0; i < pll->rate_count; i++)
62 		if (rate == rate_table[i].rate)
63 			return &rate_table[i];
64 
65 	return NULL;
66 }
67 
clk_pll1416x_recalc_rate(struct clk * clk)68 static unsigned long clk_pll1416x_recalc_rate(struct clk *clk)
69 {
70 	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
71 	u64 fvco = clk_get_parent_rate(clk);
72 	u32 mdiv, pdiv, sdiv, pll_div;
73 
74 	pll_div = readl(pll->base + 4);
75 	mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
76 	pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
77 	sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
78 
79 	fvco *= mdiv;
80 	do_div(fvco, pdiv << sdiv);
81 
82 	return fvco;
83 }
84 
clk_pll1443x_recalc_rate(struct clk * clk)85 static unsigned long clk_pll1443x_recalc_rate(struct clk *clk)
86 {
87 	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
88 	u64 fvco = clk_get_parent_rate(clk);
89 	u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1;
90 	short int kdiv;
91 
92 	pll_div_ctl0 = readl(pll->base + 4);
93 	pll_div_ctl1 = readl(pll->base + 8);
94 	mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
95 	pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
96 	sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
97 	kdiv = pll_div_ctl1 & KDIV_MASK;
98 
99 	/* fvco = (m * 65536 + k) * Fin / (p * 65536) */
100 	fvco *= (mdiv * 65536 + kdiv);
101 	pdiv *= 65536;
102 
103 	do_div(fvco, pdiv << sdiv);
104 
105 	return fvco;
106 }
107 
clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table * rate,u32 pll_div)108 static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate,
109 					  u32 pll_div)
110 {
111 	u32 old_mdiv, old_pdiv;
112 
113 	old_mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
114 	old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
115 
116 	return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv;
117 }
118 
clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table * rate,u32 pll_div_ctl0,u32 pll_div_ctl1)119 static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate,
120 					   u32 pll_div_ctl0, u32 pll_div_ctl1)
121 {
122 	u32 old_mdiv, old_pdiv, old_kdiv;
123 
124 	old_mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
125 	old_pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
126 	old_kdiv = (pll_div_ctl1 & KDIV_MASK) >> KDIV_SHIFT;
127 
128 	return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
129 		rate->kdiv != old_kdiv;
130 }
131 
clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table * rate,u32 pll_div_ctl0,u32 pll_div_ctl1)132 static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate,
133 					  u32 pll_div_ctl0, u32 pll_div_ctl1)
134 {
135 	u32 old_mdiv, old_pdiv, old_kdiv;
136 
137 	old_mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
138 	old_pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
139 	old_kdiv = (pll_div_ctl1 & KDIV_MASK) >> KDIV_SHIFT;
140 
141 	return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
142 		rate->kdiv != old_kdiv;
143 }
144 
clk_pll14xx_wait_lock(struct clk_pll14xx * pll)145 static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
146 {
147 	u32 val;
148 
149 	return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US,
150 			LOCK_TIMEOUT_US);
151 }
152 
clk_pll1416x_set_rate(struct clk * clk,unsigned long drate)153 static ulong clk_pll1416x_set_rate(struct clk *clk, unsigned long drate)
154 {
155 	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
156 	const struct imx_pll14xx_rate_table *rate;
157 	u32 tmp, div_val;
158 	int ret;
159 
160 	rate = imx_get_pll_settings(pll, drate);
161 	if (!rate) {
162 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
163 		       drate, "xxxx");
164 		return -EINVAL;
165 	}
166 
167 	tmp = readl(pll->base + 4);
168 
169 	if (!clk_pll1416x_mp_change(rate, tmp)) {
170 		tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
171 		tmp |= rate->sdiv << SDIV_SHIFT;
172 		writel(tmp, pll->base + 4);
173 
174 		return clk_pll1416x_recalc_rate(clk);
175 	}
176 
177 	/* Bypass clock and set lock to pll output lock */
178 	tmp = readl(pll->base);
179 	tmp |= LOCK_SEL_MASK;
180 	writel(tmp, pll->base);
181 
182 	/* Enable RST */
183 	tmp &= ~RST_MASK;
184 	writel(tmp, pll->base);
185 
186 	/* Enable BYPASS */
187 	tmp |= BYPASS_MASK;
188 	writel(tmp, pll->base);
189 
190 
191 	div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
192 		(rate->sdiv << SDIV_SHIFT);
193 	writel(div_val, pll->base + 0x4);
194 
195 	/*
196 	 * According to SPEC, t3 - t2 need to be greater than
197 	 * 1us and 1/FREF, respectively.
198 	 * FREF is FIN / Prediv, the prediv is [1, 63], so choose
199 	 * 3us.
200 	 */
201 	udelay(3);
202 
203 	/* Disable RST */
204 	tmp |= RST_MASK;
205 	writel(tmp, pll->base);
206 
207 	/* Wait Lock */
208 	ret = clk_pll14xx_wait_lock(pll);
209 	if (ret)
210 		return ret;
211 
212 	/* Bypass */
213 	tmp &= ~BYPASS_MASK;
214 	writel(tmp, pll->base);
215 
216 	return clk_pll1416x_recalc_rate(clk);
217 }
218 
clk_pll1443x_set_rate(struct clk * clk,unsigned long drate)219 static ulong clk_pll1443x_set_rate(struct clk *clk, unsigned long drate)
220 {
221 	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
222 	const struct imx_pll14xx_rate_table *rate;
223 	u32 tmp, div_val;
224 	int ret;
225 
226 	rate = imx_get_pll_settings(pll, drate);
227 	if (!rate) {
228 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
229 		       drate, "===");
230 		return -EINVAL;
231 	}
232 
233 	tmp = readl(pll->base + 4);
234 	div_val = readl(pll->base + 8);
235 
236 	if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) {
237 		tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
238 		tmp |= rate->sdiv << SDIV_SHIFT;
239 		writel(tmp, pll->base + 4);
240 
241 		return clk_pll1443x_recalc_rate(clk);
242 	}
243 
244 	tmp = readl(pll->base);
245 
246 	/* Enable RST */
247 	tmp &= ~RST_MASK;
248 	writel(tmp, pll->base);
249 
250 	/* Enable BYPASS */
251 	tmp |= BYPASS_MASK;
252 	writel(tmp, pll->base);
253 
254 	div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
255 		(rate->sdiv << SDIV_SHIFT);
256 	writel(div_val, pll->base + 0x4);
257 	writel(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
258 
259 	/*
260 	 * According to SPEC, t3 - t2 need to be greater than
261 	 * 1us and 1/FREF, respectively.
262 	 * FREF is FIN / Prediv, the prediv is [1, 63], so choose
263 	 * 3us.
264 	 */
265 	udelay(3);
266 
267 	/* Disable RST */
268 	tmp |= RST_MASK;
269 	writel(tmp, pll->base);
270 
271 	/* Wait Lock*/
272 	ret = clk_pll14xx_wait_lock(pll);
273 	if (ret)
274 		return ret;
275 
276 	/* Bypass */
277 	tmp &= ~BYPASS_MASK;
278 	writel(tmp, pll->base);
279 
280 	return clk_pll1443x_recalc_rate(clk);
281 }
282 
clk_pll14xx_prepare(struct clk * clk)283 static int clk_pll14xx_prepare(struct clk *clk)
284 {
285 	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
286 	u32 val;
287 
288 	/*
289 	 * RESETB = 1 from 0, PLL starts its normal
290 	 * operation after lock time
291 	 */
292 	val = readl(pll->base + GNRL_CTL);
293 	val |= RST_MASK;
294 	writel(val, pll->base + GNRL_CTL);
295 
296 	return clk_pll14xx_wait_lock(pll);
297 }
298 
clk_pll14xx_unprepare(struct clk * clk)299 static int clk_pll14xx_unprepare(struct clk *clk)
300 {
301 	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
302 	u32 val;
303 
304 	/*
305 	 * Set RST to 0, power down mode is enabled and
306 	 * every digital block is reset
307 	 */
308 	val = readl(pll->base + GNRL_CTL);
309 	val &= ~RST_MASK;
310 	writel(val, pll->base + GNRL_CTL);
311 
312 	return 0;
313 }
314 
315 static const struct clk_ops clk_pll1416x_ops = {
316 	.enable		= clk_pll14xx_prepare,
317 	.disable	= clk_pll14xx_unprepare,
318 	.set_rate	= clk_pll1416x_set_rate,
319 	.get_rate	= clk_pll1416x_recalc_rate,
320 };
321 
322 static const struct clk_ops clk_pll1443x_ops = {
323 	.enable		= clk_pll14xx_prepare,
324 	.disable	= clk_pll14xx_unprepare,
325 	.set_rate	= clk_pll1443x_set_rate,
326 	.get_rate	= clk_pll1443x_recalc_rate,
327 };
328 
imx_clk_pll14xx(const char * name,const char * parent_name,void __iomem * base,const struct imx_pll14xx_clk * pll_clk)329 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
330 			    void __iomem *base,
331 			    const struct imx_pll14xx_clk *pll_clk)
332 {
333 	struct clk_pll14xx *pll;
334 	struct clk *clk;
335 	char *type_name;
336 	int ret;
337 
338 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
339 	if (!pll)
340 		return ERR_PTR(-ENOMEM);
341 
342 	switch (pll_clk->type) {
343 	case PLL_1416X:
344 		type_name = UBOOT_DM_CLK_IMX_PLL1416X;
345 		break;
346 	case PLL_1443X:
347 		type_name = UBOOT_DM_CLK_IMX_PLL1443X;
348 		break;
349 	default:
350 		pr_err("%s: Unknown pll type for pll clk %s\n",
351 		       __func__, name);
352 		return ERR_PTR(-EINVAL);
353 	};
354 
355 	pll->base = base;
356 	pll->type = pll_clk->type;
357 	pll->rate_table = pll_clk->rate_table;
358 	pll->rate_count = pll_clk->rate_count;
359 
360 	clk = &pll->clk;
361 
362 	ret = clk_register(clk, type_name, name, parent_name);
363 	if (ret) {
364 		pr_err("%s: failed to register pll %s %d\n",
365 		       __func__, name, ret);
366 		kfree(pll);
367 		return ERR_PTR(ret);
368 	}
369 
370 	return clk;
371 }
372 
373 U_BOOT_DRIVER(clk_pll1443x) = {
374 	.name	= UBOOT_DM_CLK_IMX_PLL1443X,
375 	.id	= UCLASS_CLK,
376 	.ops	= &clk_pll1443x_ops,
377 	.flags = DM_FLAG_PRE_RELOC,
378 };
379 
380 U_BOOT_DRIVER(clk_pll1416x) = {
381 	.name	= UBOOT_DM_CLK_IMX_PLL1416X,
382 	.id	= UCLASS_CLK,
383 	.ops	= &clk_pll1416x_ops,
384 	.flags = DM_FLAG_PRE_RELOC,
385 };
386