2 #include <linux/clkdev.h>
4 #include <linux/clk-provider.h>
6 #include <linux/of_address.h>
7 #include <linux/clk-private.h>
8 #include <linux/delay.h>
9 #include <linux/rockchip/common.h>
14 struct clk_ops_table rk_clk_mux_ops_table[] = {
15 {.index = CLKOPS_TABLE_END},
20 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
21 #define div_mask(d) ((1 << ((d)->width)) - 1)
23 static u32 clk_gcd(u32 numerator, u32 denominator)
27 if (!numerator || !denominator)
29 if (numerator > denominator) {
45 static int clk_fracdiv_get_config(unsigned long rate_out, unsigned long rate,
46 u32 *numerator, u32 *denominator)
49 gcd_val = clk_gcd(rate, rate_out);
50 clk_debug("%s: frac_get_seting rate=%lu, parent=%lu, gcd=%d\n",
51 __func__, rate_out, rate, gcd_val);
54 clk_err("gcd=0, frac div is not be supported\n");
58 *numerator = rate_out / gcd_val;
59 *denominator = rate / gcd_val;
61 clk_debug("%s: frac_get_seting numerator=%d, denominator=%d, times=%d\n",
62 __func__, *numerator, *denominator,
63 *denominator / *numerator);
65 if (*numerator > 0xffff || *denominator > 0xffff ||
66 (*denominator / (*numerator)) < 20) {
67 clk_err("can't get a available nume and deno\n");
75 static int clk_fracdiv_set_rate(struct clk_hw *hw, unsigned long rate,
76 unsigned long parent_rate)
78 u32 numerator, denominator;
79 struct clk_divider *div = to_clk_divider(hw);
82 if(clk_fracdiv_get_config(rate, parent_rate,
83 &numerator, &denominator) == 0) {
84 writel(numerator << 16 | denominator, div->reg);
85 clk_debug("%s set rate=%lu,is ok\n", hw->clk->name, rate);
87 clk_err("clk_frac_div name=%s can't get rate=%lu\n",
95 static unsigned long clk_fracdiv_recalc(struct clk_hw *hw,
96 unsigned long parent_rate)
100 struct clk_divider *div = to_clk_divider(hw);
101 u32 numerator, denominator, reg_val;
103 reg_val = readl(div->reg);
107 numerator = reg_val >> 16;
108 denominator = reg_val & 0xFFFF;
109 rate64 = (u64)parent_rate * numerator;
110 do_div(rate64, denominator);
112 clk_debug("%s: %s new clock rate is %lu, prate %lu (frac %u/%u)\n",
113 __func__, hw->clk->name, rate, parent_rate,
114 numerator, denominator);
118 static long clk_fracdiv_round_rate(struct clk_hw *hw, unsigned long rate,
119 unsigned long *prate)
121 struct clk *clk = hw->clk;
122 struct clk *parent = clk->parent;
125 //FIXME: now just simply return rate
127 *frac_div request a big input rate, and its parent is always a div,
128 *so we set parent->parent->rate as best_parent_rate.
131 *prate = parent->parent->rate;
136 static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
137 unsigned long parent_rate)
139 return clk_divider_ops.recalc_rate(hw, parent_rate);
142 static long clk_divider_round_rate(struct clk_hw *hw,
143 unsigned long rate, unsigned long *prate)
145 return clk_divider_ops.round_rate(hw, rate, prate);
148 static int clk_divider_set_rate(struct clk_hw *hw,
149 unsigned long rate, unsigned long parent_rate)
151 return clk_divider_ops.set_rate(hw, rate, parent_rate);
154 static long clk_mux_with_div_determine_rate(struct clk_hw *div_hw, unsigned long rate,
155 unsigned long *best_parent_rate,
156 struct clk **best_parent_p)
158 struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL;
160 unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0;
163 parent = __clk_get_parent(clk);
165 best = __clk_get_rate(clk);
169 /* if NO_REPARENT flag set, pass through to current parent */
170 if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
171 best_prate = __clk_get_rate(parent);
172 best = clk_divider_ops.round_rate(div_hw, rate, &best_prate);
176 /* find the parent that can provide the fastest rate <= rate */
177 num_parents = clk->num_parents;
178 for (i = 0; i < num_parents; i++) {
179 parent = clk_get_parent_by_index(clk, i);
183 parent_rate = __clk_get_rate(parent);
184 now = clk_divider_ops.round_rate(div_hw, rate, &parent_rate);
186 if (now <= rate && now > best) {
187 best_parent = parent;
188 best_prate = parent_rate;
195 *best_parent_rate = best_prate;
198 *best_parent_p = best_parent;
200 clk_debug("clk name = %s, determine rate = %lu, best = %lu\n"
201 "\tbest_parent name = %s, best_prate = %lu\n",
202 clk->name, rate, best,
203 __clk_get_name(*best_parent_p), *best_parent_rate);
208 const struct clk_ops clkops_rate_auto_parent = {
209 .recalc_rate = clk_divider_recalc_rate,
210 .round_rate = clk_divider_round_rate,
211 .set_rate = clk_divider_set_rate,
212 .determine_rate = clk_mux_with_div_determine_rate,
215 static long clk_div_round_rate_even(struct clk_hw *hw, unsigned long rate,
216 unsigned long *prate)
219 struct clk_divider *divider =to_clk_divider(hw);
220 int max_div = 1 << divider->width;
222 for (i = 1; i <= max_div; i++) {
223 if (i > 1 && (i % 2 != 0))
225 if (rate >= (*prate / i))
229 return (*prate / max_div);
232 const struct clk_ops clkops_rate_evendiv = {
233 .recalc_rate = clk_divider_recalc_rate,
234 .round_rate = clk_div_round_rate_even,
235 .set_rate = clk_divider_set_rate,
238 static long clk_mux_with_evendiv_determine_rate(struct clk_hw *div_hw, unsigned long rate,
239 unsigned long *best_parent_rate,
240 struct clk **best_parent_p)
242 struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL;
244 unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0;
247 parent = __clk_get_parent(clk);
249 best = __clk_get_rate(clk);
253 /* if NO_REPARENT flag set, pass through to current parent */
254 if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
255 best_prate = __clk_get_rate(parent);
256 best = clk_div_round_rate_even(div_hw, rate, &best_prate);
260 /* find the parent that can provide the fastest rate <= rate */
261 num_parents = clk->num_parents;
262 for (i = 0; i < num_parents; i++) {
263 parent = clk_get_parent_by_index(clk, i);
267 parent_rate = __clk_get_rate(parent);
268 now = clk_div_round_rate_even(div_hw, rate, &parent_rate);
270 if (now <= rate && now > best) {
271 best_parent = parent;
272 best_prate = parent_rate;
279 *best_parent_rate = best_prate;
282 *best_parent_p = best_parent;
284 clk_debug("clk name = %s, determine rate = %lu, best = %lu\n"
285 "\tbest_parent name = %s, best_prate = %lu\n",
286 clk->name, rate, best,
287 __clk_get_name(*best_parent_p), *best_parent_rate);
292 static long clk_mux_with_evendiv_round_rate(struct clk_hw *hw, unsigned long rate,
293 unsigned long *prate)
295 return clk_div_round_rate_even(hw, rate, prate);
298 const struct clk_ops clkops_rate_mux_with_evendiv = {
299 .recalc_rate = clk_divider_recalc_rate,
300 .set_rate = clk_divider_set_rate,
301 .round_rate = clk_mux_with_evendiv_round_rate,
302 .determine_rate = clk_mux_with_evendiv_determine_rate,
305 static int clk_i2s_fracdiv_set_rate(struct clk_hw *hw, unsigned long rate,
306 unsigned long parent_rate)
308 u32 numerator, denominator;
309 struct clk_divider *div = to_clk_divider(hw);
313 if(clk_fracdiv_get_config(rate, parent_rate,
314 &numerator, &denominator) == 0) {
316 writel((numerator - 1) << 16 | denominator, div->reg);
318 writel(numerator << 16 | denominator, div->reg);
321 clk_debug("%s set rate=%lu,is ok\n", hw->clk->name, rate);
323 clk_err("clk_frac_div name=%s can't get rate=%lu\n",
324 hw->clk->name, rate);
331 const struct clk_ops clkops_rate_frac = {
332 .recalc_rate = clk_fracdiv_recalc,
333 .round_rate = clk_fracdiv_round_rate,
334 .set_rate = clk_fracdiv_set_rate,
337 const struct clk_ops clkops_rate_i2s_frac = {
338 .recalc_rate = clk_fracdiv_recalc,
339 .round_rate = clk_fracdiv_round_rate,
340 .set_rate = clk_i2s_fracdiv_set_rate,
343 static unsigned long clk_core_recalc_rate(struct clk_hw *hw,
344 unsigned long parent_rate)
346 /* As parent rate could be changed in clk_core.set_rate
347 * ops, the passing_in parent_rate may not be the newest
348 * and we should use the parent->rate instead. As a side
349 * effect, we should NOT directly set clk_core's parent
350 * (apll) rate, otherwise we will get a wrong recalc rate
351 * with clk_core_recalc_rate.
353 struct clk *parent = __clk_get_parent(hw->clk);
355 return clk_divider_recalc_rate(hw, __clk_get_rate(parent));
358 static long clk_core_determine_rate(struct clk_hw *hw, unsigned long rate,
359 unsigned long *best_parent_rate,
360 struct clk **best_parent_p)
362 struct clk *parent = __clk_get_parent(hw->clk);
364 if (IS_ERR_OR_NULL(parent)) {
365 clk_err("fail to get parent!\n");
369 return clk_round_rate(parent, rate);
372 static long clk_core_round_rate(struct clk_hw *hw, unsigned long rate,
373 unsigned long *prate)
375 return clk_core_determine_rate(hw, rate, prate, NULL);
378 static int clk_core_set_rate(struct clk_hw *hw, unsigned long rate,
379 unsigned long parent_rate)
381 struct clk *parent = __clk_get_parent(hw->clk);
382 struct clk *grand_p = __clk_get_parent(parent);
385 if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
386 clk_err("fail to get parent or grand_parent!\n");
390 ret = parent->ops->set_rate(parent->hw, rate, __clk_get_rate(grand_p));
391 parent->rate = parent->ops->recalc_rate(parent->hw,
392 __clk_get_rate(grand_p));
397 const struct clk_ops clkops_rate_core = {
398 .recalc_rate = clk_core_recalc_rate,
399 .round_rate = clk_core_round_rate,
400 .set_rate = clk_core_set_rate,
401 .determine_rate = clk_core_determine_rate,
404 /* Clk_ops for the child clk of clk_core, for example core_periph in rk3188 */
405 const struct clk_ops clkops_rate_core_peri = {
406 .recalc_rate = clk_divider_recalc_rate,
407 .round_rate = clk_divider_round_rate,
411 static unsigned long clk_ddr_recalc_rate(struct clk_hw *hw,
412 unsigned long parent_rate)
414 /* Same as clk_core, we should NOT set clk_ddr's parent
415 * (dpll) rate directly as a side effect.
417 return clk_core_recalc_rate(hw, parent_rate);
420 static long clk_ddr_determine_rate(struct clk_hw *hw, unsigned long rate,
421 unsigned long *best_parent_rate,
422 struct clk **best_parent_p)
426 if (!ddr_round_rate) {
427 /* Do nothing before ddr init */
428 best = rate;//__clk_get_rate(hw->clk);
430 /* Func provided by ddr driver */
431 best = ddr_round_rate(rate/MHZ) * MHZ;
434 clk_debug("%s: from %lu to %lu\n", __func__, rate, best);
439 static long clk_ddr_round_rate(struct clk_hw *hw, unsigned long rate,
440 unsigned long *prate)
442 return clk_ddr_determine_rate(hw, rate, prate, NULL);
445 static int clk_ddr_set_rate(struct clk_hw *hw, unsigned long rate,
446 unsigned long parent_rate)
448 struct clk *parent = __clk_get_parent(hw->clk);
449 struct clk *grand_p = __clk_get_parent(parent);
452 /* Do nothing before ddr init */
453 if (!ddr_change_freq)
456 if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
457 clk_err("fail to get parent or grand_parent!\n");
461 clk_debug("%s: will set rate = %lu\n", __func__, rate);
463 /* Func provided by ddr driver */
464 ddr_change_freq(rate/MHZ);
466 parent->rate = parent->ops->recalc_rate(parent->hw,
467 __clk_get_rate(grand_p));
472 const struct clk_ops clkops_rate_ddr = {
473 .recalc_rate = clk_ddr_recalc_rate,
474 .round_rate = clk_ddr_round_rate,
475 .set_rate = clk_ddr_set_rate,
476 .determine_rate = clk_ddr_determine_rate,
479 static unsigned long clk_3288_i2s_recalc_rate(struct clk_hw *hw,
480 unsigned long parent_rate)
485 static long clk_3288_i2s_round_rate(struct clk_hw *hw, unsigned long rate,
486 unsigned long *prate)
491 static int clk_3288_i2s_set_rate(struct clk_hw *hw, unsigned long rate,
492 unsigned long parent_rate)
494 struct clk *parent = __clk_get_parent(hw->clk);
495 struct clk *grand_p = __clk_get_parent(parent);
498 if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
502 if (parent->ops->set_rate) {
503 parent->ops->set_rate(parent->hw, rate/2, __clk_get_rate(grand_p));
504 parent->ops->set_rate(parent->hw, rate, __clk_get_rate(grand_p));
510 const struct clk_ops clkops_rate_3288_i2s = {
511 .recalc_rate = clk_3288_i2s_recalc_rate,
512 .round_rate = clk_3288_i2s_round_rate,
513 .set_rate = clk_3288_i2s_set_rate,
516 static bool usb480m_state = false;
518 static long clk_3288_usb480m_determine_rate(struct clk_hw *hw, unsigned long rate,
519 unsigned long *best_parent_rate,
520 struct clk **best_parent_p)
528 static long clk_3288_usb480m_round_rate(struct clk_hw *hw, unsigned long rate,
529 unsigned long *prate)
531 return clk_3288_usb480m_determine_rate(hw, rate, prate, NULL);
534 static int clk_3288_usb480m_set_rate(struct clk_hw *hw, unsigned long rate,
535 unsigned long parent_rate)
538 usb480m_state = false;
540 usb480m_state = true;
545 static unsigned long clk_3288_usb480m_recalc_rate(struct clk_hw *hw,
546 unsigned long parent_rate)
554 const struct clk_ops clkops_rate_3288_usb480m = {
555 .determine_rate = clk_3288_usb480m_determine_rate,
556 .set_rate = clk_3288_usb480m_set_rate,
557 .round_rate = clk_3288_usb480m_round_rate,
558 .recalc_rate = clk_3288_usb480m_recalc_rate,
561 #define RK3288_LIMIT_PLL_VIO0 (410*MHZ)
563 static long clk_3288_dclk_lcdc0_determine_rate(struct clk_hw *hw, unsigned long rate,
564 unsigned long *best_parent_rate,
565 struct clk **best_parent_p)
567 struct clk *gpll = clk_get(NULL, "clk_gpll");
568 struct clk *cpll = clk_get(NULL, "clk_cpll");
569 unsigned long best, div, prate;
572 if((rate <= (297*MHZ)) && ((297*MHZ)%rate == 0)) {
573 *best_parent_p = gpll;
575 *best_parent_rate = 297*MHZ;
577 *best_parent_p = cpll;
578 div = RK3288_LIMIT_PLL_VIO0/rate;
580 *best_parent_rate = clk_round_rate(cpll, prate);
581 best = (*best_parent_rate)/div;
587 static long clk_3288_dclk_lcdc0_round_rate(struct clk_hw *hw, unsigned long rate,
588 unsigned long *prate)
590 return clk_3288_dclk_lcdc0_determine_rate(hw, rate, prate, NULL);
593 static int clk_3288_dclk_lcdc0_set_rate(struct clk_hw *hw, unsigned long rate,
594 unsigned long parent_rate)
596 struct clk* aclk_vio0 = clk_get(NULL, "aclk_vio0");
597 struct clk* hclk_vio = clk_get(NULL, "hclk_vio");
600 clk_divider_ops.set_rate(hw, rate, parent_rate);
603 if(parent_rate == 297*MHZ)
604 parent = clk_get(NULL, "clk_gpll");
606 parent = clk_get(NULL, "clk_cpll");
608 clk_set_parent(aclk_vio0, parent);
609 clk_set_rate(aclk_vio0, __clk_get_rate(parent));
610 clk_set_rate(hclk_vio, 100*MHZ);
615 const struct clk_ops clkops_rate_3288_dclk_lcdc0 = {
616 .determine_rate = clk_3288_dclk_lcdc0_determine_rate,
617 .set_rate = clk_3288_dclk_lcdc0_set_rate,
618 .round_rate = clk_3288_dclk_lcdc0_round_rate,
619 .recalc_rate = clk_divider_recalc_rate,
622 #define RK3288_LIMIT_PLL_VIO1 (350*MHZ)
624 static long clk_3288_dclk_lcdc1_determine_rate(struct clk_hw *hw, unsigned long rate,
625 unsigned long *best_parent_rate,
626 struct clk **best_parent_p)
628 struct clk *gpll = clk_get(NULL, "clk_gpll");
629 struct clk *cpll = clk_get(NULL, "clk_cpll");
630 unsigned long best, div, prate;
633 if((rate <= (297*MHZ)) && ((297*MHZ)%rate == 0)) {
634 *best_parent_p = gpll;
636 *best_parent_rate = 297*MHZ;
638 *best_parent_p = cpll;
639 div = RK3288_LIMIT_PLL_VIO1/rate;
641 *best_parent_rate = clk_round_rate(cpll, prate);
642 best = (*best_parent_rate)/div;
648 static long clk_3288_dclk_lcdc1_round_rate(struct clk_hw *hw, unsigned long rate,
649 unsigned long *prate)
651 return clk_3288_dclk_lcdc1_determine_rate(hw, rate, prate, NULL);
654 static int clk_3288_dclk_lcdc1_set_rate(struct clk_hw *hw, unsigned long rate,
655 unsigned long parent_rate)
657 struct clk* aclk_vio1 = clk_get(NULL, "aclk_vio1");
660 clk_divider_ops.set_rate(hw, rate, parent_rate);
663 if(parent_rate == 297*MHZ)
664 parent = clk_get(NULL, "clk_gpll");
666 parent = clk_get(NULL, "clk_cpll");
668 clk_set_parent(aclk_vio1, parent);
669 clk_set_rate(aclk_vio1, __clk_get_rate(parent));
674 const struct clk_ops clkops_rate_3288_dclk_lcdc1 = {
675 .determine_rate = clk_3288_dclk_lcdc1_determine_rate,
676 .set_rate = clk_3288_dclk_lcdc1_set_rate,
677 .round_rate = clk_3288_dclk_lcdc1_round_rate,
678 .recalc_rate = clk_divider_recalc_rate,
682 struct clk_ops_table rk_clkops_rate_table[] = {
683 {.index = CLKOPS_RATE_MUX_DIV, .clk_ops = &clkops_rate_auto_parent},
684 {.index = CLKOPS_RATE_EVENDIV, .clk_ops = &clkops_rate_evendiv},
685 {.index = CLKOPS_RATE_MUX_EVENDIV, .clk_ops = &clkops_rate_mux_with_evendiv},
686 {.index = CLKOPS_RATE_I2S_FRAC, .clk_ops = &clkops_rate_i2s_frac},
687 {.index = CLKOPS_RATE_FRAC, .clk_ops = &clkops_rate_frac},
688 {.index = CLKOPS_RATE_CORE, .clk_ops = &clkops_rate_core},
689 {.index = CLKOPS_RATE_CORE_CHILD, .clk_ops = &clkops_rate_core_peri},
690 {.index = CLKOPS_RATE_DDR, .clk_ops = &clkops_rate_ddr},
691 {.index = CLKOPS_RATE_RK3288_I2S, .clk_ops = &clkops_rate_3288_i2s},
692 {.index = CLKOPS_RATE_RK3288_USB480M, .clk_ops = &clkops_rate_3288_usb480m},
693 {.index = CLKOPS_RATE_RK3288_DCLK_LCDC0,.clk_ops = &clkops_rate_3288_dclk_lcdc0},
694 {.index = CLKOPS_RATE_RK3288_DCLK_LCDC1,.clk_ops = &clkops_rate_3288_dclk_lcdc1},
695 {.index = CLKOPS_RATE_I2S, .clk_ops = NULL},
696 {.index = CLKOPS_RATE_CIFOUT, .clk_ops = NULL},
697 {.index = CLKOPS_RATE_UART, .clk_ops = NULL},
698 {.index = CLKOPS_RATE_HSADC, .clk_ops = NULL},
699 {.index = CLKOPS_RATE_MAC_REF, .clk_ops = NULL},
700 {.index = CLKOPS_TABLE_END, .clk_ops = NULL},
703 const struct clk_ops *rk_get_clkops(unsigned int idx)
706 unsigned int now_idx;
709 now_idx = rk_clkops_rate_table[i].index;
711 if ((now_idx == idx) || (now_idx == CLKOPS_TABLE_END))
712 return rk_clkops_rate_table[i].clk_ops;
717 EXPORT_SYMBOL_GPL(rk_get_clkops);