1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2023 Nuvoton Technology Corp.
4 * Author: Chi-Fang Li <cfli0@nuvoton.com>
5 */
6
7 #include <linux/bitfield.h>
8 #include <linux/clk-provider.h>
9 #include <linux/container_of.h>
10 #include <linux/device.h>
11 #include <linux/io.h>
12 #include <linux/kernel.h>
13 #include <linux/math64.h>
14 #include <linux/slab.h>
15 #include <linux/units.h>
16 #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
17
18 #include "clk-ma35d1.h"
19
20 /* PLL frequency limits */
21 #define PLL_FREF_MAX_FREQ (200 * HZ_PER_MHZ)
22 #define PLL_FREF_MIN_FREQ (1 * HZ_PER_MHZ)
23 #define PLL_FREF_M_MAX_FREQ (40 * HZ_PER_MHZ)
24 #define PLL_FREF_M_MIN_FREQ (10 * HZ_PER_MHZ)
25 #define PLL_FCLK_MAX_FREQ (2400 * HZ_PER_MHZ)
26 #define PLL_FCLK_MIN_FREQ (600 * HZ_PER_MHZ)
27 #define PLL_FCLKO_MAX_FREQ (2400 * HZ_PER_MHZ)
28 #define PLL_FCLKO_MIN_FREQ (85700 * HZ_PER_KHZ)
29 #define PLL_SS_RATE 0x77
30 #define PLL_SLOPE 0x58CFA
31
32 #define REG_PLL_CTL0_OFFSET 0x0
33 #define REG_PLL_CTL1_OFFSET 0x4
34 #define REG_PLL_CTL2_OFFSET 0x8
35
36 /* bit fields for REG_CLK_PLL0CTL0, which is SMIC PLL design */
37 #define SPLL0_CTL0_FBDIV GENMASK(7, 0)
38 #define SPLL0_CTL0_INDIV GENMASK(11, 8)
39 #define SPLL0_CTL0_OUTDIV GENMASK(13, 12)
40 #define SPLL0_CTL0_PD BIT(16)
41 #define SPLL0_CTL0_BP BIT(17)
42
43 /* bit fields for REG_CLK_PLLxCTL0 ~ REG_CLK_PLLxCTL2, where x = 2 ~ 5 */
44 #define PLL_CTL0_FBDIV GENMASK(10, 0)
45 #define PLL_CTL0_INDIV GENMASK(17, 12)
46 #define PLL_CTL0_MODE GENMASK(19, 18)
47 #define PLL_CTL0_SSRATE GENMASK(30, 20)
48 #define PLL_CTL1_PD BIT(0)
49 #define PLL_CTL1_BP BIT(1)
50 #define PLL_CTL1_OUTDIV GENMASK(6, 4)
51 #define PLL_CTL1_FRAC GENMASK(31, 24)
52 #define PLL_CTL2_SLOPE GENMASK(23, 0)
53
54 #define INDIV_MIN 1
55 #define INDIV_MAX 63
56 #define FBDIV_MIN 16
57 #define FBDIV_MAX 2047
58 #define FBDIV_FRAC_MIN 1600
59 #define FBDIV_FRAC_MAX 204700
60 #define OUTDIV_MIN 1
61 #define OUTDIV_MAX 7
62
63 #define PLL_MODE_INT 0
64 #define PLL_MODE_FRAC 1
65 #define PLL_MODE_SS 2
66
67 struct ma35d1_clk_pll {
68 struct clk_hw hw;
69 u32 id;
70 u8 mode;
71 void __iomem *ctl0_base;
72 void __iomem *ctl1_base;
73 void __iomem *ctl2_base;
74 };
75
to_ma35d1_clk_pll(struct clk_hw * _hw)76 static inline struct ma35d1_clk_pll *to_ma35d1_clk_pll(struct clk_hw *_hw)
77 {
78 return container_of(_hw, struct ma35d1_clk_pll, hw);
79 }
80
ma35d1_calc_smic_pll_freq(u32 pll0_ctl0,unsigned long parent_rate)81 static unsigned long ma35d1_calc_smic_pll_freq(u32 pll0_ctl0,
82 unsigned long parent_rate)
83 {
84 u32 m, n, p, outdiv;
85 u64 pll_freq;
86
87 if (pll0_ctl0 & SPLL0_CTL0_BP)
88 return parent_rate;
89
90 n = FIELD_GET(SPLL0_CTL0_FBDIV, pll0_ctl0);
91 m = FIELD_GET(SPLL0_CTL0_INDIV, pll0_ctl0);
92 p = FIELD_GET(SPLL0_CTL0_OUTDIV, pll0_ctl0);
93 outdiv = 1 << p;
94 pll_freq = (u64)parent_rate * n;
95 div_u64(pll_freq, m * outdiv);
96 return pll_freq;
97 }
98
ma35d1_calc_pll_freq(u8 mode,u32 * reg_ctl,unsigned long parent_rate)99 static unsigned long ma35d1_calc_pll_freq(u8 mode, u32 *reg_ctl, unsigned long parent_rate)
100 {
101 unsigned long pll_freq, x;
102 u32 m, n, p;
103
104 if (reg_ctl[1] & PLL_CTL1_BP)
105 return parent_rate;
106
107 n = FIELD_GET(PLL_CTL0_FBDIV, reg_ctl[0]);
108 m = FIELD_GET(PLL_CTL0_INDIV, reg_ctl[0]);
109 p = FIELD_GET(PLL_CTL1_OUTDIV, reg_ctl[1]);
110
111 if (mode == PLL_MODE_INT) {
112 pll_freq = (u64)parent_rate * n;
113 div_u64(pll_freq, m * p);
114 } else {
115 x = FIELD_GET(PLL_CTL1_FRAC, reg_ctl[1]);
116 /* 2 decimal places floating to integer (ex. 1.23 to 123) */
117 n = n * 100 + ((x * 100) / FIELD_MAX(PLL_CTL1_FRAC));
118 pll_freq = div_u64(parent_rate * n, 100 * m * p);
119 }
120 return pll_freq;
121 }
122
ma35d1_pll_find_closest(struct ma35d1_clk_pll * pll,unsigned long rate,unsigned long parent_rate,u32 * reg_ctl,unsigned long * freq)123 static int ma35d1_pll_find_closest(struct ma35d1_clk_pll *pll, unsigned long rate,
124 unsigned long parent_rate, u32 *reg_ctl,
125 unsigned long *freq)
126 {
127 unsigned long min_diff = ULONG_MAX;
128 int fbdiv_min, fbdiv_max;
129 int p, m, n;
130
131 *freq = 0;
132 if (rate < PLL_FCLKO_MIN_FREQ || rate > PLL_FCLKO_MAX_FREQ)
133 return -EINVAL;
134
135 if (pll->mode == PLL_MODE_INT) {
136 fbdiv_min = FBDIV_MIN;
137 fbdiv_max = FBDIV_MAX;
138 } else {
139 fbdiv_min = FBDIV_FRAC_MIN;
140 fbdiv_max = FBDIV_FRAC_MAX;
141 }
142
143 for (m = INDIV_MIN; m <= INDIV_MAX; m++) {
144 for (n = fbdiv_min; n <= fbdiv_max; n++) {
145 for (p = OUTDIV_MIN; p <= OUTDIV_MAX; p++) {
146 unsigned long tmp, fout, fclk, diff;
147
148 tmp = div_u64(parent_rate, m);
149 if (tmp < PLL_FREF_M_MIN_FREQ ||
150 tmp > PLL_FREF_M_MAX_FREQ)
151 continue; /* constrain */
152
153 fclk = div_u64(parent_rate * n, m);
154 /* for 2 decimal places */
155 if (pll->mode != PLL_MODE_INT)
156 fclk = div_u64(fclk, 100);
157
158 if (fclk < PLL_FCLK_MIN_FREQ ||
159 fclk > PLL_FCLK_MAX_FREQ)
160 continue; /* constrain */
161
162 fout = div_u64(fclk, p);
163 if (fout < PLL_FCLKO_MIN_FREQ ||
164 fout > PLL_FCLKO_MAX_FREQ)
165 continue; /* constrain */
166
167 diff = abs(rate - fout);
168 if (diff < min_diff) {
169 reg_ctl[0] = FIELD_PREP(PLL_CTL0_INDIV, m) |
170 FIELD_PREP(PLL_CTL0_FBDIV, n);
171 reg_ctl[1] = FIELD_PREP(PLL_CTL1_OUTDIV, p);
172 *freq = fout;
173 min_diff = diff;
174 if (min_diff == 0)
175 break;
176 }
177 }
178 }
179 }
180 if (*freq == 0)
181 return -EINVAL; /* cannot find even one valid setting */
182 return 0;
183 }
184
ma35d1_clk_pll_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)185 static int ma35d1_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
186 unsigned long parent_rate)
187 {
188 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
189 u32 reg_ctl[3] = { 0 };
190 unsigned long pll_freq;
191 int ret;
192
193 if (parent_rate < PLL_FREF_MIN_FREQ || parent_rate > PLL_FREF_MAX_FREQ)
194 return -EINVAL;
195
196 ret = ma35d1_pll_find_closest(pll, rate, parent_rate, reg_ctl, &pll_freq);
197 if (ret != 0)
198 return ret;
199
200 switch (pll->mode) {
201 case PLL_MODE_INT:
202 reg_ctl[0] |= FIELD_PREP(PLL_CTL0_MODE, PLL_MODE_INT);
203 break;
204 case PLL_MODE_FRAC:
205 reg_ctl[0] |= FIELD_PREP(PLL_CTL0_MODE, PLL_MODE_FRAC);
206 break;
207 case PLL_MODE_SS:
208 reg_ctl[0] |= FIELD_PREP(PLL_CTL0_MODE, PLL_MODE_SS) |
209 FIELD_PREP(PLL_CTL0_SSRATE, PLL_SS_RATE);
210 reg_ctl[2] = FIELD_PREP(PLL_CTL2_SLOPE, PLL_SLOPE);
211 break;
212 }
213 reg_ctl[1] |= PLL_CTL1_PD;
214
215 writel_relaxed(reg_ctl[0], pll->ctl0_base);
216 writel_relaxed(reg_ctl[1], pll->ctl1_base);
217 writel_relaxed(reg_ctl[2], pll->ctl2_base);
218 return 0;
219 }
220
ma35d1_clk_pll_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)221 static unsigned long ma35d1_clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
222 {
223 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
224 u32 reg_ctl[3];
225 unsigned long pll_freq;
226
227 if (parent_rate < PLL_FREF_MIN_FREQ || parent_rate > PLL_FREF_MAX_FREQ)
228 return 0;
229
230 switch (pll->id) {
231 case CAPLL:
232 reg_ctl[0] = readl_relaxed(pll->ctl0_base);
233 pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], parent_rate);
234 return pll_freq;
235 case DDRPLL:
236 case APLL:
237 case EPLL:
238 case VPLL:
239 reg_ctl[0] = readl_relaxed(pll->ctl0_base);
240 reg_ctl[1] = readl_relaxed(pll->ctl1_base);
241 pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, parent_rate);
242 return pll_freq;
243 }
244 return 0;
245 }
246
ma35d1_clk_pll_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)247 static int ma35d1_clk_pll_determine_rate(struct clk_hw *hw,
248 struct clk_rate_request *req)
249 {
250 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
251 u32 reg_ctl[3] = { 0 };
252 unsigned long pll_freq;
253 long ret;
254
255 if (req->best_parent_rate < PLL_FREF_MIN_FREQ || req->best_parent_rate > PLL_FREF_MAX_FREQ)
256 return -EINVAL;
257
258 ret = ma35d1_pll_find_closest(pll, req->rate, req->best_parent_rate,
259 reg_ctl, &pll_freq);
260 if (ret < 0)
261 return ret;
262
263 switch (pll->id) {
264 case CAPLL:
265 reg_ctl[0] = readl_relaxed(pll->ctl0_base);
266 pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], req->best_parent_rate);
267 req->rate = pll_freq;
268
269 return 0;
270 case DDRPLL:
271 case APLL:
272 case EPLL:
273 case VPLL:
274 reg_ctl[0] = readl_relaxed(pll->ctl0_base);
275 reg_ctl[1] = readl_relaxed(pll->ctl1_base);
276 pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, req->best_parent_rate);
277 req->rate = pll_freq;
278
279 return 0;
280 }
281
282 req->rate = 0;
283
284 return 0;
285 }
286
ma35d1_clk_pll_is_prepared(struct clk_hw * hw)287 static int ma35d1_clk_pll_is_prepared(struct clk_hw *hw)
288 {
289 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
290 u32 val = readl_relaxed(pll->ctl1_base);
291
292 return !(val & PLL_CTL1_PD);
293 }
294
ma35d1_clk_pll_prepare(struct clk_hw * hw)295 static int ma35d1_clk_pll_prepare(struct clk_hw *hw)
296 {
297 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
298 u32 val;
299
300 val = readl_relaxed(pll->ctl1_base);
301 val &= ~PLL_CTL1_PD;
302 writel_relaxed(val, pll->ctl1_base);
303 return 0;
304 }
305
ma35d1_clk_pll_unprepare(struct clk_hw * hw)306 static void ma35d1_clk_pll_unprepare(struct clk_hw *hw)
307 {
308 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
309 u32 val;
310
311 val = readl_relaxed(pll->ctl1_base);
312 val |= PLL_CTL1_PD;
313 writel_relaxed(val, pll->ctl1_base);
314 }
315
316 static const struct clk_ops ma35d1_clk_pll_ops = {
317 .is_prepared = ma35d1_clk_pll_is_prepared,
318 .prepare = ma35d1_clk_pll_prepare,
319 .unprepare = ma35d1_clk_pll_unprepare,
320 .set_rate = ma35d1_clk_pll_set_rate,
321 .recalc_rate = ma35d1_clk_pll_recalc_rate,
322 .determine_rate = ma35d1_clk_pll_determine_rate,
323 };
324
325 static const struct clk_ops ma35d1_clk_fixed_pll_ops = {
326 .recalc_rate = ma35d1_clk_pll_recalc_rate,
327 .determine_rate = ma35d1_clk_pll_determine_rate,
328 };
329
ma35d1_reg_clk_pll(struct device * dev,u32 id,u8 u8mode,const char * name,struct clk_hw * parent_hw,void __iomem * base)330 struct clk_hw *ma35d1_reg_clk_pll(struct device *dev, u32 id, u8 u8mode, const char *name,
331 struct clk_hw *parent_hw, void __iomem *base)
332 {
333 struct clk_parent_data pdata = { .index = 0 };
334 struct clk_init_data init = {};
335 struct ma35d1_clk_pll *pll;
336 struct clk_hw *hw;
337 int ret;
338
339 pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
340 if (!pll)
341 return ERR_PTR(-ENOMEM);
342
343 pll->id = id;
344 pll->mode = u8mode;
345 pll->ctl0_base = base + REG_PLL_CTL0_OFFSET;
346 pll->ctl1_base = base + REG_PLL_CTL1_OFFSET;
347 pll->ctl2_base = base + REG_PLL_CTL2_OFFSET;
348
349 init.name = name;
350 init.flags = 0;
351 pdata.hw = parent_hw;
352 init.parent_data = &pdata;
353 init.num_parents = 1;
354
355 if (id == CAPLL || id == DDRPLL)
356 init.ops = &ma35d1_clk_fixed_pll_ops;
357 else
358 init.ops = &ma35d1_clk_pll_ops;
359
360 pll->hw.init = &init;
361 hw = &pll->hw;
362
363 ret = devm_clk_hw_register(dev, hw);
364 if (ret)
365 return ERR_PTR(ret);
366 return hw;
367 }
368 EXPORT_SYMBOL_GPL(ma35d1_reg_clk_pll);
369