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