1 #include <linux/slab.h>
8 //static unsigned long lpj_gpll;
11 extern void __iomem *reg_start;
12 #define RK30_CRU_BASE (reg_start)
14 #define cru_readl(offset) readl(RK30_CRU_BASE + offset)
15 #define cru_writel(v, offset) do {writel(v, RK30_CRU_BASE + offset); dsb();} \
19 //#define grf_readl(offset) readl_relaxed(RK30_GRF_BASE + offset)
22 #define PLLS_IN_NORM(pll_id) (((cru_readl(CRU_MODE_CON)&PLL_MODE_MSK(pll_id))\
23 ==(PLL_MODE_NORM(pll_id)&PLL_MODE_MSK(pll_id)))\
24 &&!(cru_readl(PLL_CONS(pll_id,3))&PLL_BYPASS))
27 static const struct apll_clk_set apll_table[] = {
28 // (_mhz, nr, nf, no, _periph_div, _aclk_div)
29 _APLL_SET_CLKS(2208, 1, 92, 1, 8, 81),
30 _APLL_SET_CLKS(2184, 1, 91, 1, 8, 81),
31 _APLL_SET_CLKS(2160, 1, 90, 1, 8, 81),
32 _APLL_SET_CLKS(2136, 1, 89, 1, 8, 81),
33 _APLL_SET_CLKS(2112, 1, 88, 1, 8, 81),
34 _APLL_SET_CLKS(2088, 1, 87, 1, 8, 81),
35 _APLL_SET_CLKS(2064, 1, 86, 1, 8, 81),
36 _APLL_SET_CLKS(2040, 1, 85, 1, 8, 81),
37 _APLL_SET_CLKS(2016, 1, 84, 1, 8, 81),
38 _APLL_SET_CLKS(1992, 1, 83, 1, 8, 81),
39 _APLL_SET_CLKS(1968, 1, 82, 1, 8, 81),
40 _APLL_SET_CLKS(1944, 1, 81, 1, 8, 81),
41 _APLL_SET_CLKS(1920, 1, 80, 1, 8, 81),
42 _APLL_SET_CLKS(1896, 1, 79, 1, 8, 81),
43 _APLL_SET_CLKS(1872, 1, 78, 1, 8, 81),
44 _APLL_SET_CLKS(1848, 1, 77, 1, 8, 81),
45 _APLL_SET_CLKS(1824, 1, 76, 1, 8, 81),
46 _APLL_SET_CLKS(1800, 1, 75, 1, 8, 81),
47 _APLL_SET_CLKS(1776, 1, 74, 1, 8, 81),
48 _APLL_SET_CLKS(1752, 1, 73, 1, 8, 81),
49 _APLL_SET_CLKS(1728, 1, 72, 1, 8, 81),
50 _APLL_SET_CLKS(1704, 1, 71, 1, 8, 81),
51 _APLL_SET_CLKS(1680, 1, 70, 1, 8, 41),
52 _APLL_SET_CLKS(1656, 1, 69, 1, 8, 41),
53 _APLL_SET_CLKS(1632, 1, 68, 1, 8, 41),
54 _APLL_SET_CLKS(1608, 1, 67, 1, 8, 41),
55 _APLL_SET_CLKS(1560, 1, 65, 1, 8, 41),
56 _APLL_SET_CLKS(1512, 1, 63, 1, 8, 41),
57 _APLL_SET_CLKS(1488, 1, 62, 1, 8, 41),
58 _APLL_SET_CLKS(1464, 1, 61, 1, 8, 41),
59 _APLL_SET_CLKS(1440, 1, 60, 1, 8, 41),
60 _APLL_SET_CLKS(1416, 1, 59, 1, 8, 41),
61 _APLL_SET_CLKS(1392, 1, 58, 1, 8, 41),
62 _APLL_SET_CLKS(1368, 1, 57, 1, 8, 41),
63 _APLL_SET_CLKS(1344, 1, 56, 1, 8, 41),
64 _APLL_SET_CLKS(1320, 1, 55, 1, 8, 41),
65 _APLL_SET_CLKS(1296, 1, 54, 1, 8, 41),
66 _APLL_SET_CLKS(1272, 1, 53, 1, 8, 41),
67 _APLL_SET_CLKS(1248, 1, 52, 1, 8, 41),
68 _APLL_SET_CLKS(1224, 1, 51, 1, 8, 41),
69 _APLL_SET_CLKS(1200, 1, 50, 1, 8, 41),
70 _APLL_SET_CLKS(1176, 1, 49, 1, 8, 41),
71 _APLL_SET_CLKS(1128, 1, 47, 1, 8, 41),
72 _APLL_SET_CLKS(1104, 1, 46, 1, 8, 41),
73 _APLL_SET_CLKS(1008, 1, 84, 2, 8, 41),
74 _APLL_SET_CLKS(912, 1, 76, 2, 8, 41),
75 _APLL_SET_CLKS(888, 1, 74, 2, 8, 41),
76 _APLL_SET_CLKS(816, 1, 68, 2, 8, 41),
77 _APLL_SET_CLKS(792, 1, 66, 2, 8, 41),
78 _APLL_SET_CLKS(696, 1, 58, 2, 8, 41),
79 _APLL_SET_CLKS(600, 1, 50, 2, 4, 41),
80 _APLL_SET_CLKS(552, 1, 92, 4, 4, 41),
81 _APLL_SET_CLKS(504, 1, 84, 4, 4, 41),
82 _APLL_SET_CLKS(408, 1, 68, 4, 4, 21),
83 _APLL_SET_CLKS(312, 1, 52, 4, 2, 21),
84 _APLL_SET_CLKS(252, 1, 84, 8, 2, 21),
85 _APLL_SET_CLKS(216, 1, 72, 8, 2, 21),
86 _APLL_SET_CLKS(126, 1, 84, 16, 2, 11),
87 _APLL_SET_CLKS(48, 1, 32, 16, 2, 11),
88 _APLL_SET_CLKS(0, 1, 32, 16, 2, 11),
91 static const struct pll_clk_set pll_com_table[] = {
92 _PLL_SET_CLKS(1200000, 1, 50, 1),
93 _PLL_SET_CLKS(1188000, 2, 99, 1),
94 _PLL_SET_CLKS(891000, 8, 594, 2),
95 _PLL_SET_CLKS(768000, 1, 64, 2),
96 _PLL_SET_CLKS(594000, 2, 198, 4),
97 _PLL_SET_CLKS(408000, 1, 68, 4),
98 _PLL_SET_CLKS(384000, 2, 128, 4),
99 _PLL_SET_CLKS(360000, 1, 60, 4),
100 _PLL_SET_CLKS(300000, 1, 50, 4),
101 _PLL_SET_CLKS(297000, 2, 198, 8),
102 _PLL_SET_CLKS(148500, 2, 99, 8),
103 _PLL_SET_CLKS(0, 0, 0, 0),
107 static void pll_wait_lock(int pll_idx)
113 u32 pll_state[4] = {1, 0, 2, 3};
114 u32 bit = 0x20u << pll_state[pll_idx];
115 int delay = 24000000;
117 if (regfile_readl(GRF_SOC_STATUS0) & bit)
122 clk_err("PLL_ID=%d\npll_con0=%08x\npll_con1=%08x\n"
123 "pll_con2=%08x\npll_con3=%08x\n",
125 cru_readl(PLL_CONS(pll_idx, 0)),
126 cru_readl(PLL_CONS(pll_idx, 1)),
127 cru_readl(PLL_CONS(pll_idx, 2)),
128 cru_readl(PLL_CONS(pll_idx, 3)));
130 clk_err("wait pll bit 0x%x time out!\n", bit);
138 static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
139 unsigned long parent_rate)
141 struct clk_pll *pll = to_clk_pll(hw);
145 if (PLLS_IN_NORM(pll_id)) {
146 u32 pll_con0 = cru_readl(PLL_CONS(pll_id, 0));
147 u32 pll_con1 = cru_readl(PLL_CONS(pll_id, 1));
149 u64 rate64 = (u64)parent_rate * PLL_NF(pll_con1);
151 do_div(rate64, PLL_NR(pll_con0));
152 do_div(rate64, PLL_NO(pll_con0));
157 clk_debug("pll id=%d slow mode\n", pll_id);
160 clk_debug("pll id=%d, recalc rate =%lu\n", pll->id, rate);
166 /* get rate that is most close to target */
167 static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
168 const struct apll_clk_set *table)
170 const struct apll_clk_set *ps, *pt;
174 if (pt->rate == rate) {
179 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
189 /* get rate that is most close to target */
190 static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
191 const struct pll_clk_set *table)
193 const struct pll_clk_set *ps, *pt;
197 if (pt->rate == rate) {
202 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
212 static long clk_apll_round_rate(struct clk_hw *hw, unsigned long rate,
213 unsigned long *prate)
215 return (apll_get_best_set(rate, apll_table)->rate);
218 static long clk_pll_com_round_rate(struct clk_hw *hw, unsigned long rate,
219 unsigned long *prate)
221 return (pll_com_get_best_set(rate, pll_com_table)->rate);
224 static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
225 unsigned long *prate)
227 struct clk_pll *pll = to_clk_pll(hw);
228 struct clk *parent = __clk_get_parent(hw->clk);
231 if (parent && (rate==__clk_get_rate(parent))) {
232 clk_debug("pll id=%d round rate=%lu equal to parent rate\n",
239 rate_out = clk_apll_round_rate(hw, rate, prate);
243 rate_out = clk_pll_com_round_rate(hw, rate, prate);
252 static int _pll_clk_set_rate(struct pll_clk_set *clk_set, u8 pll_id,
255 unsigned long flags = 0;
258 clk_debug("_pll_clk_set_rate start!\n");
261 spin_lock_irqsave(lock, flags);
264 cru_writel(PLL_MODE_SLOW(pll_id), CRU_MODE_CON);
265 cru_writel((0x1<<(16+1))|(0x1<<1), PLL_CONS(pll_id, 3));
272 cru_writel(clk_set->pllcon0, PLL_CONS(pll_id, 0));
273 cru_writel(clk_set->pllcon1, PLL_CONS(pll_id, 1));
275 rk30_clock_udelay(1);
277 cru_writel((0x1<<(16+1)), PLL_CONS(pll_id, 3));
279 pll_wait_lock(pll_id);
282 cru_writel(PLL_MODE_NORM(pll_id), CRU_MODE_CON);
285 spin_unlock_irqrestore(lock, flags);
287 clk_debug("pll id=%d, dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
289 cru_readl(PLL_CONS(pll_id,0)),
290 cru_readl(PLL_CONS(pll_id,1)),
291 cru_readl(CRU_MODE_CON));
293 clk_debug("_pll_clk_set_rate end!\n");
298 static int clk_pll_com_set_rate(struct clk_hw *hw, unsigned long rate,
299 unsigned long parent_rate)
301 struct clk_pll *pll = to_clk_pll(hw);
302 struct pll_clk_set *clk_set = (struct pll_clk_set *)(pll_com_table);
306 if (rate == parent_rate) {
307 clk_debug("pll id=%d set rate=%lu equal to parent rate\n",
309 cru_writel(PLL_MODE_SLOW(pll->id), CRU_MODE_CON);
310 cru_writel((0x1 << (16+1)) | (0x1<<1), PLL_CONS(pll->id, 3));
311 clk_debug("pll id=%d enter slow mode, set rate OK!\n", pll->id);
315 while(clk_set->rate) {
316 if (clk_set->rate == rate) {
322 if (clk_set->rate == rate) {
323 ret = _pll_clk_set_rate(clk_set, pll->id, pll->lock);
324 clk_debug("pll id=%d set rate=%lu OK!\n", pll->id, rate);
326 clk_err("pll id=%d is no corresponding rate=%lu\n",
337 #define USE_ARM_GPLL 1
339 static int clk_apll_set_rate(struct clk_hw *hw, unsigned long rate,
340 unsigned long parent_rate)
342 struct clk_pll *pll = to_clk_pll(hw);
343 struct clk *clk = hw->clk;
344 struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
345 unsigned long arm_gpll_rate;
346 const struct apll_clk_set *ps;
347 u32 old_aclk_div = 0, new_aclk_div = 0;
353 if (rate == parent_rate) {
354 clk_debug("pll id=%d set rate=%lu equal to parent rate\n",
356 cru_writel(PLL_MODE_SLOW(pll->id), CRU_MODE_CON);
357 cru_writel((0x1 << (16+1)) | (0x1<<1), PLL_CONS(pll->id, 3));
358 clk_debug("pll id=%d enter slow mode, set rate OK!\n", pll->id);
366 /* prepare arm_gpll before reparent clk_core to it */
368 clk_err("clk arm_gpll is NULL!\n");
372 /* In rk3188, arm_gpll and cpu_gpll share a same gate,
373 * and aclk_cpu selects cpu_gpll as parent, thus this
374 * gate must keep enabled.
377 if (clk_prepare(arm_gpll)) {
378 clk_err("fail to prepare arm_gpll path\n");
379 clk_unprepare(arm_gpll);
383 if (clk_enable(arm_gpll)) {
384 clk_err("fail to enable arm_gpll path\n");
385 clk_disable(arm_gpll);
386 clk_unprepare(arm_gpll);
391 arm_gpll_rate = __clk_get_rate(arm_gpll);
392 temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
393 temp_div = (temp_div == 0) ? 1 : temp_div;
394 if (temp_div > CORE_CLK_MAX_DIV) {
395 clk_debug("temp_div %d > max_div %d\n", temp_div,
397 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
398 __clk_get_rate(clk), arm_gpll_rate);
399 //clk_disable(arm_gpll);
400 //clk_unprepare(arm_gpll);
404 local_irq_save(flags);
406 /* firstly set div, then select arm_gpll path */
407 cru_writel(CORE_CLK_DIV_W_MSK|CORE_CLK_DIV(temp_div), CRU_CLKSELS_CON(0));
408 cru_writel(CORE_SEL_PLL_W_MSK|CORE_SEL_GPLL, CRU_CLKSELS_CON(0));
411 //loops_per_jiffy = lpj_gpll / temp_div;
414 local_irq_restore(flags);
416 clk_debug("temp select arm_gpll path, get rate %lu\n",
417 arm_gpll_rate/temp_div);
418 clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
422 ps = apll_get_best_set(rate, apll_table);
423 clk_debug("apll will set rate %lu\n", ps->rate);
424 clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
425 ps->pllcon0, ps->pllcon1, ps->pllcon2,
426 ps->clksel0, ps->clksel1);
428 local_irq_save(flags);
430 /* If core src don't select gpll, apll need to enter slow mode
435 cru_writel(PLL_MODE_SLOW(pll->id), CRU_MODE_CON);
438 cru_writel((0x1<<(16+1))|(0x1<<1), PLL_CONS(pll->id, 3));
445 cru_writel(ps->pllcon0, PLL_CONS(pll->id, 0));
446 cru_writel(ps->pllcon1, PLL_CONS(pll->id, 1));
448 rk30_clock_udelay(1);
450 /* PLL power up and wait for locked */
451 cru_writel((0x1<<(16+1)), PLL_CONS(pll->id, 3));
452 pll_wait_lock(pll->id);
454 old_aclk_div = GET_CORE_ACLK_VAL(cru_readl(CRU_CLKSELS_CON(1)) &
456 new_aclk_div = GET_CORE_ACLK_VAL(ps->clksel1 & CORE_ACLK_MSK);
458 if (new_aclk_div >= old_aclk_div) {
459 cru_writel(ps->clksel0, CRU_CLKSELS_CON(0));
460 cru_writel(ps->clksel1, CRU_CLKSELS_CON(1));
463 /* PLL return from slow mode */
466 cru_writel(PLL_MODE_NORM(pll->id), CRU_MODE_CON);
468 /* reparent to apll, and set div to 1 */
470 cru_writel(CORE_SEL_PLL_W_MSK|CORE_SEL_APLL, CRU_CLKSELS_CON(0));
471 cru_writel(CORE_CLK_DIV_W_MSK|CORE_CLK_DIV(1), CRU_CLKSELS_CON(0));
474 if (old_aclk_div > new_aclk_div) {
475 cru_writel(ps->clksel0, CRU_CLKSELS_CON(0));
476 cru_writel(ps->clksel1, CRU_CLKSELS_CON(1));
479 //loops_per_jiffy = ps->lpj;
482 local_irq_restore(flags);
486 //clk_disable(arm_gpll);
487 //clk_unprepare(arm_gpll);
490 //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
492 clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
494 cru_readl(PLL_CONS(pll->id, 0)),cru_readl(PLL_CONS(pll->id, 1)),
495 cru_readl(PLL_CONS(pll->id, 2)),cru_readl(PLL_CONS(pll->id, 3)),
496 cru_readl(CRU_CLKSELS_CON(0)),cru_readl(CRU_CLKSELS_CON(1)));
501 static int clk_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
502 unsigned long parent_rate)
507 static int clk_gpll_set_rate(struct clk_hw *hw, unsigned long rate,
508 unsigned long parent_rate)
510 int ret = clk_pll_com_set_rate(hw, rate, parent_rate);
513 // lpj_gpll = CLK_LOOPS_RECALC(clk_pll_recalc_rate(hw, parent_rate));
518 static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
519 unsigned long parent_rate)
521 struct clk_pll *pll = to_clk_pll(hw);
526 ret = clk_apll_set_rate(hw, rate, parent_rate);
530 ret = clk_dpll_set_rate(hw, rate, parent_rate);
534 ret = clk_gpll_set_rate(hw, rate, parent_rate);
538 ret = clk_pll_com_set_rate(hw, rate, parent_rate);
546 const struct clk_ops clk_pll_ops = {
547 .recalc_rate = clk_pll_recalc_rate,
548 .round_rate = clk_pll_round_rate,
549 .set_rate = clk_pll_set_rate,
552 EXPORT_SYMBOL_GPL(clk_pll_ops);
555 struct clk *rk_clk_register_pll(struct device *dev, const char *name,
556 const char *parent_name, unsigned long flags, void __iomem *reg,
557 u32 width, u8 id, spinlock_t *lock)
561 struct clk_init_data init;
564 clk_debug("%s: pll name = %s, id = %d, register start!\n",__func__,name,id);
567 if(id >= END_PLL_ID){
568 clk_err("%s: PLL id = %d >= END_PLL_ID = %d\n", __func__,
570 return ERR_PTR(-EINVAL);
574 /* allocate the pll */
575 pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
577 clk_err("%s: could not allocate pll clk\n", __func__);
578 return ERR_PTR(-ENOMEM);
583 init.parent_names = (parent_name ? &parent_name: NULL);
584 init.num_parents = (parent_name ? 1 : 0);
585 init.ops = &clk_pll_ops;
587 /* struct clk_pll assignments */
592 pll->hw.init = &init;
594 /* register the clock */
595 clk = clk_register(dev, &pll->hw);
600 clk_debug("%s: pll name = %s, id = %d, register finish!\n",__func__,name,id);