xref: /linux/drivers/clk/eswin/clk.c (revision 53597deca0e38c30e6cd4ba2114fa42d2bcd85bb)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
4  * All rights reserved.
5  *
6  * Authors:
7  *	Yifeng Huang <huangyifeng@eswincomputing.com>
8  *	Xuyang Dong <dongxuyang@eswincomputing.com>
9  */
10 
11 #include <linux/bitfield.h>
12 #include <linux/clk-provider.h>
13 #include <linux/iopoll.h>
14 #include <linux/math.h>
15 #include <linux/platform_device.h>
16 #include <linux/slab.h>
17 
18 #include "common.h"
19 
20 #define PLL_EN_MASK		GENMASK(1, 0)
21 #define PLL_REFDIV_MASK		GENMASK(17, 12)
22 #define PLL_FBDIV_MASK		GENMASK(31, 20)
23 #define PLL_FRAC_MASK		GENMASK(27, 4)
24 #define PLL_POSTDIV1_MASK	GENMASK(10, 8)
25 #define PLL_POSTDIV2_MASK	GENMASK(18, 16)
26 
27 struct eswin_clock_data *eswin_clk_init(struct platform_device *pdev,
28 					size_t nr_clks)
29 {
30 	struct eswin_clock_data *eclk_data;
31 
32 	eclk_data = devm_kzalloc(&pdev->dev,
33 				 struct_size(eclk_data, clk_data.hws, nr_clks),
34 				 GFP_KERNEL);
35 	if (!eclk_data)
36 		return ERR_PTR(-ENOMEM);
37 
38 	eclk_data->base = devm_platform_ioremap_resource(pdev, 0);
39 	if (IS_ERR(eclk_data->base))
40 		return ERR_PTR(-EINVAL);
41 
42 	eclk_data->clk_data.num = nr_clks;
43 	spin_lock_init(&eclk_data->lock);
44 
45 	return eclk_data;
46 }
47 EXPORT_SYMBOL_GPL(eswin_clk_init);
48 
49 /**
50  * eswin_calc_pll - calculate PLL values
51  * @frac_val: fractional divider
52  * @fbdiv_val: feedback divider
53  * @rate: reference rate
54  * @parent_rate: parent rate
55  *
56  *   Calculate PLL values for frac and fbdiv:
57  *	fbdiv = rate * 4 / parent_rate
58  *	frac = (rate * 4 % parent_rate * (2 ^ 24)) / parent_rate
59  */
60 static void eswin_calc_pll(u32 *frac_val, u32 *fbdiv_val, unsigned long rate,
61 			   unsigned long parent_rate)
62 {
63 	u32 rem;
64 	u64 tmp;
65 
66 	/* step 1: rate * 4 */
67 	tmp = rate * 4;
68 	/* step 2: use do_div() to get the quotient(tmp) and remainder(rem) */
69 	rem = do_div(tmp, (u32)parent_rate);
70 	/* fbdiv = rate * 4 / parent_rate */
71 	*fbdiv_val = (u32)tmp;
72 	/*
73 	 * step 3: rem << 24
74 	 * 24: 24-bit fractional accuracy
75 	 */
76 	tmp = (u64)rem << 24;
77 	/* step 4: use do_div() to get the quotient(tmp) */
78 	do_div(tmp, (u32)parent_rate);
79 	/* frac = (rate * 4 % parent_rate * (2 ^ 24)) / parent_rate */
80 	*frac_val = (u32)tmp;
81 }
82 
83 static inline struct eswin_clk_pll *to_pll_clk(struct clk_hw *hw)
84 {
85 	return container_of(hw, struct eswin_clk_pll, hw);
86 }
87 
88 static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
89 			    unsigned long parent_rate)
90 {
91 	struct eswin_clk_pll *clk = to_pll_clk(hw);
92 	u32 frac_val, fbdiv_val, val, mask;
93 	int ret;
94 
95 	eswin_calc_pll(&frac_val, &fbdiv_val, rate, parent_rate);
96 
97 	/* First, disable pll */
98 	val = readl_relaxed(clk->ctrl_reg0);
99 	val &= ~PLL_EN_MASK;
100 	val |= FIELD_PREP(PLL_EN_MASK, 0);
101 	writel_relaxed(val, clk->ctrl_reg0);
102 
103 	val = readl_relaxed(clk->ctrl_reg0);
104 	val &= ~(PLL_REFDIV_MASK | PLL_FBDIV_MASK);
105 	val |= FIELD_PREP(PLL_FBDIV_MASK, fbdiv_val);
106 	val |= FIELD_PREP(PLL_REFDIV_MASK, 1);
107 	writel_relaxed(val, clk->ctrl_reg0);
108 
109 	val = readl_relaxed(clk->ctrl_reg1);
110 	val &= ~PLL_FRAC_MASK;
111 	val |= FIELD_PREP(PLL_FRAC_MASK, frac_val);
112 	writel_relaxed(val, clk->ctrl_reg1);
113 
114 	val = readl_relaxed(clk->ctrl_reg2);
115 	val &= ~(PLL_POSTDIV1_MASK | PLL_POSTDIV2_MASK);
116 	val |= FIELD_PREP(PLL_POSTDIV1_MASK, 1);
117 	val |= FIELD_PREP(PLL_POSTDIV2_MASK, 1);
118 	writel_relaxed(val, clk->ctrl_reg2);
119 
120 	/* Last, enable pll */
121 	val = readl_relaxed(clk->ctrl_reg0);
122 	val &= ~PLL_EN_MASK;
123 	val |= FIELD_PREP(PLL_EN_MASK, 1);
124 	writel_relaxed(val, clk->ctrl_reg0);
125 
126 	/* Usually the pll will lock in 50us */
127 	mask = GENMASK(clk->lock_shift + clk->lock_width - 1, clk->lock_shift);
128 	ret = readl_poll_timeout(clk->status_reg, val, val & mask, 1, 50 * 2);
129 	if (ret)
130 		pr_err("failed to lock the pll!\n");
131 
132 	return ret;
133 }
134 
135 static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
136 					 unsigned long parent_rate)
137 {
138 	struct eswin_clk_pll *clk = to_pll_clk(hw);
139 	u64 fbdiv_val, frac_val, tmp;
140 	u32 rem, val;
141 
142 	val = readl_relaxed(clk->ctrl_reg0);
143 	val &= PLL_FBDIV_MASK;
144 	fbdiv_val = (val >> clk->fbdiv_shift);
145 
146 	val = readl_relaxed(clk->ctrl_reg1);
147 	val &= PLL_FRAC_MASK;
148 	frac_val = (val >> clk->frac_shift);
149 
150 	/* rate = 24000000 * (fbdiv + frac / (2 ^ 24)) / 4 */
151 	tmp = parent_rate * frac_val;
152 	rem = do_div(tmp, BIT(24));
153 	if (rem)
154 		tmp = parent_rate * fbdiv_val + tmp + 1;
155 	else
156 		tmp = parent_rate * fbdiv_val + tmp;
157 
158 	do_div(tmp, 4);
159 
160 	return tmp;
161 }
162 
163 static int clk_pll_determine_rate(struct clk_hw *hw,
164 				  struct clk_rate_request *req)
165 {
166 	struct eswin_clk_pll *clk = to_pll_clk(hw);
167 
168 	req->rate = clamp(req->rate, clk->min_rate, clk->max_rate);
169 	req->min_rate = clk->min_rate;
170 	req->max_rate = clk->max_rate;
171 
172 	return 0;
173 }
174 
175 int eswin_clk_register_fixed_rate(struct device *dev,
176 				  struct eswin_fixed_rate_clock *clks,
177 				  int nums, struct eswin_clock_data *data)
178 {
179 	struct clk_hw *clk_hw;
180 	int i;
181 
182 	for (i = 0; i < nums; i++) {
183 		clk_hw = devm_clk_hw_register_fixed_rate(dev, clks[i].name,
184 							 NULL, clks[i].flags,
185 							 clks[i].rate);
186 		if (IS_ERR(clk_hw))
187 			return PTR_ERR(clk_hw);
188 
189 		clks[i].hw = *clk_hw;
190 		data->clk_data.hws[clks[i].id] = clk_hw;
191 	}
192 
193 	return 0;
194 }
195 EXPORT_SYMBOL_GPL(eswin_clk_register_fixed_rate);
196 
197 static const struct clk_ops eswin_clk_pll_ops = {
198 	.set_rate = clk_pll_set_rate,
199 	.recalc_rate = clk_pll_recalc_rate,
200 	.determine_rate = clk_pll_determine_rate,
201 };
202 
203 int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks,
204 			   int nums, struct eswin_clock_data *data)
205 {
206 	struct eswin_clk_pll *p_clk = NULL;
207 	struct clk_init_data init;
208 	struct clk_hw *clk_hw;
209 	int i, ret;
210 
211 	p_clk = devm_kzalloc(dev, sizeof(*p_clk) * nums, GFP_KERNEL);
212 	if (!p_clk)
213 		return -ENOMEM;
214 
215 	for (i = 0; i < nums; i++) {
216 		p_clk->id = clks[i].id;
217 		p_clk->ctrl_reg0 = data->base + clks[i].ctrl_reg0;
218 		p_clk->fbdiv_shift = clks[i].fbdiv_shift;
219 
220 		p_clk->ctrl_reg1 = data->base + clks[i].ctrl_reg1;
221 		p_clk->frac_shift = clks[i].frac_shift;
222 
223 		p_clk->ctrl_reg2 = data->base + clks[i].ctrl_reg2;
224 
225 		p_clk->status_reg = data->base + clks[i].status_reg;
226 		p_clk->lock_shift = clks[i].lock_shift;
227 		p_clk->lock_width = clks[i].lock_width;
228 
229 		p_clk->max_rate = clks[i].max_rate;
230 		p_clk->min_rate = clks[i].min_rate;
231 
232 		init.name = clks[i].name;
233 		init.flags = 0;
234 		init.parent_data = clks[i].parent_data;
235 		init.num_parents = 1;
236 		init.ops = &eswin_clk_pll_ops;
237 		p_clk->hw.init = &init;
238 
239 		clk_hw = &p_clk->hw;
240 
241 		ret = devm_clk_hw_register(dev, clk_hw);
242 		if (ret)
243 			return ret;
244 
245 		clks[i].hw = *clk_hw;
246 		data->clk_data.hws[clks[i].id] = clk_hw;
247 		p_clk++;
248 	}
249 
250 	return 0;
251 }
252 EXPORT_SYMBOL_GPL(eswin_clk_register_pll);
253 
254 int eswin_clk_register_fixed_factor(struct device *dev,
255 				    struct eswin_fixed_factor_clock *clks,
256 				    int nums, struct eswin_clock_data *data)
257 {
258 	struct clk_hw *clk_hw;
259 	int i;
260 
261 	for (i = 0; i < nums; i++) {
262 		clk_hw = devm_clk_hw_register_fixed_factor_index(dev, clks[i].name,
263 								 clks[i].parent_data->index,
264 								 clks[i].flags, clks[i].mult,
265 								 clks[i].div);
266 
267 		if (IS_ERR(clk_hw))
268 			return PTR_ERR(clk_hw);
269 
270 		clks[i].hw = *clk_hw;
271 		data->clk_data.hws[clks[i].id] = clk_hw;
272 	}
273 
274 	return 0;
275 }
276 EXPORT_SYMBOL_GPL(eswin_clk_register_fixed_factor);
277 
278 int eswin_clk_register_mux(struct device *dev, struct eswin_mux_clock *clks,
279 			   int nums, struct eswin_clock_data *data)
280 {
281 	struct clk_hw *clk_hw;
282 	int i;
283 
284 	for (i = 0; i < nums; i++) {
285 		clk_hw = devm_clk_hw_register_mux_parent_data_table(dev, clks[i].name,
286 								    clks[i].parent_data,
287 								    clks[i].num_parents,
288 								    clks[i].flags,
289 								    data->base + clks[i].reg,
290 								    clks[i].shift, clks[i].width,
291 								    clks[i].mux_flags,
292 								    clks[i].table, &data->lock);
293 
294 		if (IS_ERR(clk_hw))
295 			return PTR_ERR(clk_hw);
296 
297 		clks[i].hw = *clk_hw;
298 		data->clk_data.hws[clks[i].id] = clk_hw;
299 	}
300 
301 	return 0;
302 }
303 EXPORT_SYMBOL_GPL(eswin_clk_register_mux);
304 
305 static unsigned int _eswin_get_val(unsigned int div, unsigned long flags,
306 				   u8 width)
307 {
308 	unsigned int maxdiv;
309 
310 	maxdiv = clk_div_mask(width);
311 	div = div > maxdiv ? maxdiv : div;
312 
313 	if (flags & ESWIN_PRIV_DIV_MIN_2)
314 		return (div < 2) ? 2 : div;
315 
316 	return div;
317 }
318 
319 static unsigned int eswin_div_get_val(unsigned long rate,
320 				      unsigned long parent_rate, u8 width,
321 				      unsigned long flags)
322 {
323 	unsigned int div;
324 
325 	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
326 
327 	return _eswin_get_val(div, flags, width);
328 }
329 
330 static inline struct eswin_divider_clock *to_div_clk(struct clk_hw *hw)
331 {
332 	return container_of(hw, struct eswin_divider_clock, hw);
333 }
334 
335 static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
336 			    unsigned long parent_rate)
337 {
338 	struct eswin_divider_clock *dclk = to_div_clk(hw);
339 	unsigned long flags;
340 	unsigned int value;
341 	u32 val;
342 
343 	value = eswin_div_get_val(rate, parent_rate, dclk->width,
344 				  dclk->priv_flag);
345 
346 	spin_lock_irqsave(dclk->lock, flags);
347 
348 	val = readl_relaxed(dclk->ctrl_reg);
349 	val &= ~(clk_div_mask(dclk->width) << dclk->shift);
350 	val |= (u32)value << dclk->shift;
351 	writel_relaxed(val, dclk->ctrl_reg);
352 
353 	spin_unlock_irqrestore(dclk->lock, flags);
354 
355 	return 0;
356 }
357 
358 static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
359 					 unsigned long parent_rate)
360 {
361 	struct eswin_divider_clock *dclk = to_div_clk(hw);
362 	unsigned int div, val;
363 
364 	val = readl_relaxed(dclk->ctrl_reg) >> dclk->shift;
365 	val &= clk_div_mask(dclk->width);
366 	div = _eswin_get_val(val, dclk->priv_flag, dclk->width);
367 
368 	return DIV_ROUND_UP_ULL((u64)parent_rate, div);
369 }
370 
371 static int eswin_clk_bestdiv(unsigned long rate,
372 			     unsigned long best_parent_rate, u8 width,
373 			     unsigned long flags)
374 {
375 	unsigned long bestdiv, up_rate, down_rate;
376 	int up, down;
377 
378 	if (!rate)
379 		rate = 1;
380 
381 	/* closest round */
382 	up = DIV_ROUND_UP_ULL((u64)best_parent_rate, rate);
383 	down = best_parent_rate / rate;
384 
385 	up_rate = DIV_ROUND_UP_ULL((u64)best_parent_rate, up);
386 	down_rate = DIV_ROUND_UP_ULL((u64)best_parent_rate, down);
387 
388 	bestdiv = (rate - up_rate) <= (down_rate - rate) ? up : down;
389 
390 	return bestdiv;
391 }
392 
393 static int clk_div_determine_rate(struct clk_hw *hw,
394 				  struct clk_rate_request *req)
395 {
396 	struct eswin_divider_clock *dclk = to_div_clk(hw);
397 	int div;
398 
399 	div = eswin_clk_bestdiv(req->rate, req->best_parent_rate, dclk->width,
400 				dclk->priv_flag);
401 	div = _eswin_get_val(div, dclk->priv_flag, dclk->width);
402 	req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, div);
403 
404 	return 0;
405 }
406 
407 static const struct clk_ops eswin_clk_div_ops = {
408 	.set_rate = clk_div_set_rate,
409 	.recalc_rate = clk_div_recalc_rate,
410 	.determine_rate = clk_div_determine_rate,
411 };
412 
413 struct clk_hw *eswin_register_clkdiv(struct device *dev, unsigned int id,
414 				     const char *name,
415 				     const struct clk_hw *parent_hw,
416 				     unsigned long flags, void __iomem *reg,
417 				     u8 shift, u8 width,
418 				     unsigned long clk_divider_flags,
419 				     unsigned long priv_flag, spinlock_t *lock)
420 {
421 	struct eswin_divider_clock *dclk;
422 	struct clk_init_data init;
423 	struct clk_hw *clk_hw;
424 	int ret;
425 
426 	dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL);
427 	if (!dclk)
428 		return ERR_PTR(-ENOMEM);
429 
430 	init.name = name;
431 	init.ops = &eswin_clk_div_ops;
432 	init.flags = flags;
433 	init.parent_hws = &parent_hw;
434 	init.num_parents = 1;
435 
436 	/* struct clk_divider assignments */
437 	dclk->id = id;
438 	dclk->ctrl_reg = reg;
439 	dclk->shift = shift;
440 	dclk->width = width;
441 	dclk->div_flags = clk_divider_flags;
442 	dclk->priv_flag = priv_flag;
443 	dclk->lock = lock;
444 	dclk->hw.init = &init;
445 
446 	/* register the clock */
447 	clk_hw = &dclk->hw;
448 	ret = devm_clk_hw_register(dev, clk_hw);
449 	if (ret) {
450 		dev_err(dev, "failed to register divider clock!\n");
451 		return ERR_PTR(ret);
452 	}
453 
454 	return clk_hw;
455 }
456 EXPORT_SYMBOL_GPL(eswin_register_clkdiv);
457 
458 int eswin_clk_register_divider(struct device *dev,
459 			       struct eswin_divider_clock *clks,
460 			       int nums, struct eswin_clock_data *data)
461 {
462 	struct clk_hw *clk_hw;
463 	int i;
464 
465 	for (i = 0; i < nums; i++) {
466 		clk_hw = devm_clk_hw_register_divider_parent_data(dev, clks[i].name,
467 								  clks[i].parent_data,
468 								  clks[i].flags,
469 								  data->base + clks[i].reg,
470 								  clks[i].shift, clks[i].width,
471 								  clks[i].div_flags, &data->lock);
472 
473 		if (IS_ERR(clk_hw))
474 			return PTR_ERR(clk_hw);
475 
476 		clks[i].hw = *clk_hw;
477 		data->clk_data.hws[clks[i].id] = clk_hw;
478 	}
479 
480 	return 0;
481 }
482 EXPORT_SYMBOL_GPL(eswin_clk_register_divider);
483 
484 int eswin_clk_register_gate(struct device *dev, struct eswin_gate_clock *clks,
485 			    int nums, struct eswin_clock_data *data)
486 {
487 	struct clk_hw *clk_hw;
488 	int i;
489 
490 	for (i = 0; i < nums; i++) {
491 		clk_hw = devm_clk_hw_register_gate_parent_data(dev, clks[i].name,
492 							       clks[i].parent_data,
493 							       clks[i].flags,
494 							       data->base + clks[i].reg,
495 							       clks[i].bit_idx, clks[i].gate_flags,
496 							       &data->lock);
497 
498 		if (IS_ERR(clk_hw))
499 			return PTR_ERR(clk_hw);
500 
501 		clks[i].hw = *clk_hw;
502 		data->clk_data.hws[clks[i].id] = clk_hw;
503 	}
504 
505 	return 0;
506 }
507 EXPORT_SYMBOL_GPL(eswin_clk_register_gate);
508 
509 int eswin_clk_register_clks(struct device *dev, struct eswin_clk_info *clks,
510 			    int nums, struct eswin_clock_data *data)
511 {
512 	struct eswin_clk_info *info;
513 	const struct clk_hw *phw = NULL;
514 	struct clk_hw *hw;
515 	int i;
516 
517 	for (i = 0; i < nums; i++) {
518 		info = &clks[i];
519 		switch (info->type) {
520 		case CLK_FIXED_FACTOR: {
521 			const struct eswin_fixed_factor_clock *factor;
522 
523 			factor = &info->data.factor;
524 			phw = data->clk_data.hws[info->pid];
525 			hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, factor->name, phw,
526 									 factor->flags,
527 									 factor->mult,
528 									 factor->div);
529 			break;
530 		}
531 		case CLK_MUX: {
532 			const struct eswin_mux_clock *mux = &info->data.mux;
533 
534 			hw = devm_clk_hw_register_mux_parent_data_table(dev, mux->name,
535 									mux->parent_data,
536 									mux->num_parents,
537 									mux->flags,
538 									data->base + mux->reg,
539 									mux->shift, mux->width,
540 									mux->mux_flags,
541 									mux->table, &data->lock);
542 			break;
543 		}
544 		case CLK_DIVIDER: {
545 			const struct eswin_divider_clock *div = &info->data.div;
546 
547 			phw = data->clk_data.hws[info->pid];
548 			if (div->priv_flag)
549 				hw = eswin_register_clkdiv(dev, div->id, div->name, phw,
550 							   div->flags, data->base + div->reg,
551 							   div->shift, div->width, div->div_flags,
552 							   div->priv_flag, &data->lock);
553 			else
554 				hw = devm_clk_hw_register_divider_parent_hw(dev, div->name, phw,
555 									    div->flags,
556 									    data->base + div->reg,
557 									    div->shift, div->width,
558 									    div->div_flags,
559 									    &data->lock);
560 			break;
561 		}
562 		case CLK_GATE: {
563 			const struct eswin_gate_clock *gate = &info->data.gate;
564 
565 			phw = data->clk_data.hws[info->pid];
566 			hw = devm_clk_hw_register_gate_parent_hw(dev, gate->name, phw,
567 								 gate->flags,
568 								 data->base + gate->reg,
569 								 gate->bit_idx, gate->gate_flags,
570 								 &data->lock);
571 			break;
572 		}
573 		default:
574 			dev_err(dev, "Unidentifiable clock type!\n");
575 			return -EINVAL;
576 		}
577 		if (IS_ERR(hw))
578 			return PTR_ERR(hw);
579 
580 		info->hw = *hw;
581 		data->clk_data.hws[info->id] = hw;
582 	}
583 
584 	return 0;
585 }
586 EXPORT_SYMBOL_GPL(eswin_clk_register_clks);
587