xref: /linux/drivers/clk/nuvoton/clk-ma35d1-pll.c (revision db10cb9b)
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 
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 
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 
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 
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 
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 
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 
247 static long ma35d1_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
248 				      unsigned long *parent_rate)
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 (*parent_rate < PLL_FREF_MIN_FREQ || *parent_rate > PLL_FREF_MAX_FREQ)
256 		return -EINVAL;
257 
258 	ret = ma35d1_pll_find_closest(pll, rate, *parent_rate, reg_ctl, &pll_freq);
259 	if (ret < 0)
260 		return ret;
261 
262 	switch (pll->id) {
263 	case CAPLL:
264 		reg_ctl[0] = readl_relaxed(pll->ctl0_base);
265 		pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], *parent_rate);
266 		return pll_freq;
267 	case DDRPLL:
268 	case APLL:
269 	case EPLL:
270 	case VPLL:
271 		reg_ctl[0] = readl_relaxed(pll->ctl0_base);
272 		reg_ctl[1] = readl_relaxed(pll->ctl1_base);
273 		pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, *parent_rate);
274 		return pll_freq;
275 	}
276 	return 0;
277 }
278 
279 static int ma35d1_clk_pll_is_prepared(struct clk_hw *hw)
280 {
281 	struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
282 	u32 val = readl_relaxed(pll->ctl1_base);
283 
284 	return !(val & PLL_CTL1_PD);
285 }
286 
287 static int ma35d1_clk_pll_prepare(struct clk_hw *hw)
288 {
289 	struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
290 	u32 val;
291 
292 	val = readl_relaxed(pll->ctl1_base);
293 	val &= ~PLL_CTL1_PD;
294 	writel_relaxed(val, pll->ctl1_base);
295 	return 0;
296 }
297 
298 static void ma35d1_clk_pll_unprepare(struct clk_hw *hw)
299 {
300 	struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw);
301 	u32 val;
302 
303 	val = readl_relaxed(pll->ctl1_base);
304 	val |= PLL_CTL1_PD;
305 	writel_relaxed(val, pll->ctl1_base);
306 }
307 
308 static const struct clk_ops ma35d1_clk_pll_ops = {
309 	.is_prepared = ma35d1_clk_pll_is_prepared,
310 	.prepare = ma35d1_clk_pll_prepare,
311 	.unprepare = ma35d1_clk_pll_unprepare,
312 	.set_rate = ma35d1_clk_pll_set_rate,
313 	.recalc_rate = ma35d1_clk_pll_recalc_rate,
314 	.round_rate = ma35d1_clk_pll_round_rate,
315 };
316 
317 static const struct clk_ops ma35d1_clk_fixed_pll_ops = {
318 	.recalc_rate = ma35d1_clk_pll_recalc_rate,
319 	.round_rate = ma35d1_clk_pll_round_rate,
320 };
321 
322 struct clk_hw *ma35d1_reg_clk_pll(struct device *dev, u32 id, u8 u8mode, const char *name,
323 				  struct clk_hw *parent_hw, void __iomem *base)
324 {
325 	struct clk_parent_data pdata = { .index = 0 };
326 	struct clk_init_data init = {};
327 	struct ma35d1_clk_pll *pll;
328 	struct clk_hw *hw;
329 	int ret;
330 
331 	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
332 	if (!pll)
333 		return ERR_PTR(-ENOMEM);
334 
335 	pll->id = id;
336 	pll->mode = u8mode;
337 	pll->ctl0_base = base + REG_PLL_CTL0_OFFSET;
338 	pll->ctl1_base = base + REG_PLL_CTL1_OFFSET;
339 	pll->ctl2_base = base + REG_PLL_CTL2_OFFSET;
340 
341 	init.name = name;
342 	init.flags = 0;
343 	pdata.hw = parent_hw;
344 	init.parent_data = &pdata;
345 	init.num_parents = 1;
346 
347 	if (id == CAPLL || id == DDRPLL)
348 		init.ops = &ma35d1_clk_fixed_pll_ops;
349 	else
350 		init.ops = &ma35d1_clk_pll_ops;
351 
352 	pll->hw.init = &init;
353 	hw = &pll->hw;
354 
355 	ret = devm_clk_hw_register(dev, hw);
356 	if (ret)
357 		return ERR_PTR(ret);
358 	return hw;
359 }
360 EXPORT_SYMBOL_GPL(ma35d1_reg_clk_pll);
361