1 #include <linux/slab.h>
3 #include <linux/rockchip/cpu.h>
9 static const struct pll_clk_set pll_com_table[] = {
10 _RK3188_PLL_SET_CLKS(1250000, 12, 625, 1),
11 _RK3188_PLL_SET_CLKS(1200000, 1, 50, 1),
12 _RK3188_PLL_SET_CLKS(1188000, 2, 99, 1),
13 _RK3188_PLL_SET_CLKS(891000, 8, 594, 2),
14 _RK3188_PLL_SET_CLKS(768000, 1, 64, 2),
15 _RK3188_PLL_SET_CLKS(594000, 2, 198, 4),
16 _RK3188_PLL_SET_CLKS(500000, 3, 250, 4),
17 _RK3188_PLL_SET_CLKS(408000, 1, 68, 4),
18 _RK3188_PLL_SET_CLKS(396000, 1, 66, 4),
19 _RK3188_PLL_SET_CLKS(384000, 2, 128, 4),
20 _RK3188_PLL_SET_CLKS(360000, 1, 60, 4),
21 _RK3188_PLL_SET_CLKS(300000, 1, 50, 4),
22 _RK3188_PLL_SET_CLKS(297000, 2, 198, 8),
23 _RK3188_PLL_SET_CLKS(148500, 2, 99, 8),
24 _RK3188_PLL_SET_CLKS(0, 0, 0, 0),
27 static const struct apll_clk_set rk3188_apll_table[] = {
28 // (_mhz, nr, nf, no, _periph_div, _aclk_div)
29 _RK3188_APLL_SET_CLKS(2208, 1, 92, 1, 8, 81),
30 _RK3188_APLL_SET_CLKS(2184, 1, 91, 1, 8, 81),
31 _RK3188_APLL_SET_CLKS(2160, 1, 90, 1, 8, 81),
32 _RK3188_APLL_SET_CLKS(2136, 1, 89, 1, 8, 81),
33 _RK3188_APLL_SET_CLKS(2112, 1, 88, 1, 8, 81),
34 _RK3188_APLL_SET_CLKS(2088, 1, 87, 1, 8, 81),
35 _RK3188_APLL_SET_CLKS(2064, 1, 86, 1, 8, 81),
36 _RK3188_APLL_SET_CLKS(2040, 1, 85, 1, 8, 81),
37 _RK3188_APLL_SET_CLKS(2016, 1, 84, 1, 8, 81),
38 _RK3188_APLL_SET_CLKS(1992, 1, 83, 1, 8, 81),
39 _RK3188_APLL_SET_CLKS(1968, 1, 82, 1, 8, 81),
40 _RK3188_APLL_SET_CLKS(1944, 1, 81, 1, 8, 81),
41 _RK3188_APLL_SET_CLKS(1920, 1, 80, 1, 8, 81),
42 _RK3188_APLL_SET_CLKS(1896, 1, 79, 1, 8, 81),
43 _RK3188_APLL_SET_CLKS(1872, 1, 78, 1, 8, 81),
44 _RK3188_APLL_SET_CLKS(1848, 1, 77, 1, 8, 81),
45 _RK3188_APLL_SET_CLKS(1824, 1, 76, 1, 8, 81),
46 _RK3188_APLL_SET_CLKS(1800, 1, 75, 1, 8, 81),
47 _RK3188_APLL_SET_CLKS(1776, 1, 74, 1, 8, 81),
48 _RK3188_APLL_SET_CLKS(1752, 1, 73, 1, 8, 81),
49 _RK3188_APLL_SET_CLKS(1728, 1, 72, 1, 8, 81),
50 _RK3188_APLL_SET_CLKS(1704, 1, 71, 1, 8, 81),
51 _RK3188_APLL_SET_CLKS(1680, 1, 70, 1, 8, 41),
52 _RK3188_APLL_SET_CLKS(1656, 1, 69, 1, 8, 41),
53 _RK3188_APLL_SET_CLKS(1632, 1, 68, 1, 8, 41),
54 _RK3188_APLL_SET_CLKS(1608, 1, 67, 1, 8, 41),
55 _RK3188_APLL_SET_CLKS(1560, 1, 65, 1, 8, 41),
56 _RK3188_APLL_SET_CLKS(1512, 1, 63, 1, 8, 41),
57 _RK3188_APLL_SET_CLKS(1488, 1, 62, 1, 8, 41),
58 _RK3188_APLL_SET_CLKS(1464, 1, 61, 1, 8, 41),
59 _RK3188_APLL_SET_CLKS(1440, 1, 60, 1, 8, 41),
60 _RK3188_APLL_SET_CLKS(1416, 1, 59, 1, 8, 41),
61 _RK3188_APLL_SET_CLKS(1392, 1, 58, 1, 8, 41),
62 _RK3188_APLL_SET_CLKS(1368, 1, 57, 1, 8, 41),
63 _RK3188_APLL_SET_CLKS(1344, 1, 56, 1, 8, 41),
64 _RK3188_APLL_SET_CLKS(1320, 1, 55, 1, 8, 41),
65 _RK3188_APLL_SET_CLKS(1296, 1, 54, 1, 8, 41),
66 _RK3188_APLL_SET_CLKS(1272, 1, 53, 1, 8, 41),
67 _RK3188_APLL_SET_CLKS(1248, 1, 52, 1, 8, 41),
68 _RK3188_APLL_SET_CLKS(1224, 1, 51, 1, 8, 41),
69 _RK3188_APLL_SET_CLKS(1200, 1, 50, 1, 8, 41),
70 _RK3188_APLL_SET_CLKS(1176, 1, 49, 1, 8, 41),
71 _RK3188_APLL_SET_CLKS(1128, 1, 47, 1, 8, 41),
72 _RK3188_APLL_SET_CLKS(1104, 1, 46, 1, 8, 41),
73 _RK3188_APLL_SET_CLKS(1008, 1, 84, 2, 8, 41),
74 _RK3188_APLL_SET_CLKS(912, 1, 76, 2, 8, 41),
75 _RK3188_APLL_SET_CLKS(888, 1, 74, 2, 8, 41),
76 _RK3188_APLL_SET_CLKS(816, 1, 68, 2, 8, 41),
77 _RK3188_APLL_SET_CLKS(792, 1, 66, 2, 8, 41),
78 _RK3188_APLL_SET_CLKS(696, 1, 58, 2, 8, 41),
79 _RK3188_APLL_SET_CLKS(600, 1, 50, 2, 4, 41),
80 _RK3188_APLL_SET_CLKS(552, 1, 92, 4, 4, 41),
81 _RK3188_APLL_SET_CLKS(504, 1, 84, 4, 4, 41),
82 _RK3188_APLL_SET_CLKS(408, 1, 68, 4, 4, 21),
83 _RK3188_APLL_SET_CLKS(312, 1, 52, 4, 2, 21),
84 _RK3188_APLL_SET_CLKS(252, 1, 84, 8, 2, 21),
85 _RK3188_APLL_SET_CLKS(216, 1, 72, 8, 2, 21),
86 _RK3188_APLL_SET_CLKS(126, 1, 84, 16, 2, 11),
87 _RK3188_APLL_SET_CLKS(48, 1, 32, 16, 2, 11),
88 _RK3188_APLL_SET_CLKS(0, 1, 32, 16, 2, 11),
91 static const struct apll_clk_set rk3288_apll_table[] = {
92 // (_mhz, nr, nf, no, l2ram, m0, mp, atclk, pclk_dbg)
93 _RK3288_APLL_SET_CLKS(2208, 1, 92, 1, 2, 2, 4, 4, 4),
94 _RK3288_APLL_SET_CLKS(2184, 1, 91, 1, 2, 2, 4, 4, 4),
95 _RK3288_APLL_SET_CLKS(2160, 1, 90, 1, 2, 2, 4, 4, 4),
96 _RK3288_APLL_SET_CLKS(2136, 1, 89, 1, 2, 2, 4, 4, 4),
97 _RK3288_APLL_SET_CLKS(2112, 1, 88, 1, 2, 2, 4, 4, 4),
98 _RK3288_APLL_SET_CLKS(2088, 1, 87, 1, 2, 2, 4, 4, 4),
99 _RK3288_APLL_SET_CLKS(2064, 1, 86, 1, 2, 2, 4, 4, 4),
100 _RK3288_APLL_SET_CLKS(2040, 1, 85, 1, 2, 2, 4, 4, 4),
101 _RK3288_APLL_SET_CLKS(2016, 1, 84, 1, 2, 2, 4, 4, 4),
102 _RK3288_APLL_SET_CLKS(1992, 1, 83, 1, 2, 2, 4, 4, 4),
103 _RK3288_APLL_SET_CLKS(1968, 1, 82, 1, 2, 2, 4, 4, 4),
104 _RK3288_APLL_SET_CLKS(1944, 1, 81, 1, 2, 2, 4, 4, 4),
105 _RK3288_APLL_SET_CLKS(1920, 1, 80, 1, 2, 2, 4, 4, 4),
106 _RK3288_APLL_SET_CLKS(1896, 1, 79, 1, 2, 2, 4, 4, 4),
107 _RK3288_APLL_SET_CLKS(1872, 1, 78, 1, 2, 2, 4, 4, 4),
108 _RK3288_APLL_SET_CLKS(1848, 1, 77, 1, 2, 2, 4, 4, 4),
109 _RK3288_APLL_SET_CLKS(1824, 1, 76, 1, 2, 2, 4, 4, 4),
110 _RK3288_APLL_SET_CLKS(1800, 1, 75, 1, 2, 2, 4, 4, 4),
111 _RK3288_APLL_SET_CLKS(1776, 1, 74, 1, 2, 2, 4, 4, 4),
112 _RK3288_APLL_SET_CLKS(1752, 1, 73, 1, 2, 2, 4, 4, 4),
113 _RK3288_APLL_SET_CLKS(1728, 1, 72, 1, 2, 2, 4, 4, 4),
114 _RK3288_APLL_SET_CLKS(1704, 1, 71, 1, 2, 2, 4, 4, 4),
115 _RK3288_APLL_SET_CLKS(1680, 1, 70, 1, 2, 2, 4, 4, 4),
116 _RK3288_APLL_SET_CLKS(1656, 1, 69, 1, 2, 2, 4, 4, 4),
117 _RK3288_APLL_SET_CLKS(1632, 1, 68, 1, 2, 2, 4, 4, 4),
118 _RK3288_APLL_SET_CLKS(1608, 1, 67, 1, 2, 2, 4, 4, 4),
119 _RK3288_APLL_SET_CLKS(1560, 1, 65, 1, 2, 2, 4, 4, 4),
120 _RK3288_APLL_SET_CLKS(1512, 1, 63, 1, 2, 2, 4, 4, 4),
121 _RK3288_APLL_SET_CLKS(1488, 1, 62, 1, 2, 2, 4, 4, 4),
122 _RK3288_APLL_SET_CLKS(1464, 1, 61, 1, 2, 2, 4, 4, 4),
123 _RK3288_APLL_SET_CLKS(1440, 1, 60, 1, 2, 2, 4, 4, 4),
124 _RK3288_APLL_SET_CLKS(1416, 1, 59, 1, 2, 2, 4, 4, 4),
125 _RK3288_APLL_SET_CLKS(1392, 1, 58, 1, 2, 2, 4, 4, 4),
126 _RK3288_APLL_SET_CLKS(1368, 1, 57, 1, 2, 2, 4, 4, 4),
127 _RK3288_APLL_SET_CLKS(1344, 1, 56, 1, 2, 2, 4, 4, 4),
128 _RK3288_APLL_SET_CLKS(1320, 1, 55, 1, 2, 2, 4, 4, 4),
129 _RK3288_APLL_SET_CLKS(1296, 1, 54, 1, 2, 2, 4, 4, 4),
130 _RK3288_APLL_SET_CLKS(1272, 1, 53, 1, 2, 2, 4, 4, 4),
131 _RK3288_APLL_SET_CLKS(1248, 1, 52, 1, 2, 2, 4, 4, 4),
132 _RK3288_APLL_SET_CLKS(1224, 1, 51, 1, 2, 2, 4, 4, 4),
133 _RK3288_APLL_SET_CLKS(1200, 1, 50, 1, 2, 2, 4, 4, 4),
134 _RK3288_APLL_SET_CLKS(1176, 1, 49, 1, 2, 2, 4, 4, 4),
135 _RK3288_APLL_SET_CLKS(1128, 1, 47, 1, 2, 2, 4, 4, 4),
136 _RK3288_APLL_SET_CLKS(1104, 1, 46, 1, 2, 2, 4, 4, 4),
137 _RK3288_APLL_SET_CLKS(1008, 1, 84, 2, 2, 2, 4, 4, 4),
138 _RK3288_APLL_SET_CLKS(912, 1, 76, 2, 2, 2, 4, 4, 4),
139 _RK3288_APLL_SET_CLKS(888, 1, 74, 2, 2, 2, 4, 4, 4),
140 _RK3288_APLL_SET_CLKS(816, 1, 68, 2, 2, 2, 4, 4, 4),
141 _RK3288_APLL_SET_CLKS(792, 1, 66, 2, 2, 2, 4, 4, 4),
142 _RK3288_APLL_SET_CLKS(696, 1, 58, 2, 2, 2, 4, 4, 4),
143 _RK3288_APLL_SET_CLKS(600, 1, 50, 2, 2, 2, 4, 4, 4),
144 _RK3288_APLL_SET_CLKS(552, 1, 92, 4, 2, 2, 4, 4, 4),
145 _RK3288_APLL_SET_CLKS(504, 1, 84, 4, 2, 2, 4, 4, 4),
146 _RK3288_APLL_SET_CLKS(408, 1, 68, 4, 2, 2, 4, 4, 4),
147 _RK3288_APLL_SET_CLKS(312, 1, 52, 4, 2, 2, 4, 4, 4),
148 _RK3288_APLL_SET_CLKS(252, 1, 84, 8, 2, 2, 4, 4, 4),
149 _RK3288_APLL_SET_CLKS(216, 1, 72, 8, 2, 2, 4, 4, 4),
150 _RK3288_APLL_SET_CLKS(126, 2, 84, 8, 2, 2, 4, 4, 4),
151 _RK3288_APLL_SET_CLKS(48, 2, 32, 8, 2, 2, 4, 4, 4),
152 _RK3288_APLL_SET_CLKS(0, 1, 32, 16, 2, 2, 4, 4, 4),
155 static void pll_wait_lock(struct clk_hw *hw)
157 struct clk_pll *pll = to_clk_pll(hw);
158 int delay = 24000000;
162 if (grf_readl(pll->status_offset) & (1 << pll->status_shift))
168 clk_err("pll %s: can't lock! status_shift=%u\n"
169 "pll_con0=%08x\npll_con1=%08x\n"
170 "pll_con2=%08x\npll_con3=%08x\n",
171 __clk_get_name(hw->clk),
173 readl(pll->reg + RK3188_PLL_CON(0)),
174 readl(pll->reg + RK3188_PLL_CON(1)),
175 readl(pll->reg + RK3188_PLL_CON(2)),
176 readl(pll->reg + RK3188_PLL_CON(3)));
182 /* get rate that is most close to target */
183 static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
184 const struct apll_clk_set *table)
186 const struct apll_clk_set *ps, *pt;
190 if (pt->rate == rate) {
195 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
205 /* get rate that is most close to target */
206 static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
207 const struct pll_clk_set *table)
209 const struct pll_clk_set *ps, *pt;
213 if (pt->rate == rate) {
218 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
228 /* CLK_PLL_3188 type ops */
229 static unsigned long clk_pll_recalc_rate_3188(struct clk_hw *hw,
230 unsigned long parent_rate)
232 struct clk_pll *pll = to_clk_pll(hw);
236 if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
237 u32 pll_con0 = readl(pll->reg + RK3188_PLL_CON(0));
238 u32 pll_con1 = readl(pll->reg + RK3188_PLL_CON(1));
240 u64 rate64 = (u64)parent_rate * RK3188_PLL_NF(pll_con1);
242 do_div(rate64, RK3188_PLL_NR(pll_con0));
243 do_div(rate64, RK3188_PLL_NO(pll_con0));
249 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
252 clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
257 static long clk_pll_round_rate_3188(struct clk_hw *hw, unsigned long rate,
258 unsigned long *prate)
260 struct clk *parent = __clk_get_parent(hw->clk);
262 if (parent && (rate==__clk_get_rate(parent))) {
263 clk_debug("pll %s round rate=%lu equal to parent rate\n",
264 __clk_get_name(hw->clk), rate);
268 return (pll_com_get_best_set(rate, pll_com_table)->rate);
271 static int _pll_clk_set_rate_3188(struct pll_clk_set *clk_set,
274 struct clk_pll *pll = to_clk_pll(hw);
275 unsigned long flags = 0;
278 clk_debug("%s start!\n", __func__);
281 spin_lock_irqsave(pll->lock, flags);
284 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
286 writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
293 writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
294 writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
299 writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
304 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
307 spin_unlock_irqrestore(pll->lock, flags);
309 clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
310 __clk_get_name(hw->clk),
311 readl(pll->reg + RK3188_PLL_CON(0)),
312 readl(pll->reg + RK3188_PLL_CON(1)),
313 cru_readl(pll->mode_offset));
315 clk_debug("%s end!\n", __func__);
320 static int clk_pll_set_rate_3188(struct clk_hw *hw, unsigned long rate,
321 unsigned long parent_rate)
323 struct clk_pll *pll = to_clk_pll(hw);
324 struct pll_clk_set *clk_set = (struct pll_clk_set *)(pll_com_table);
328 if (rate == parent_rate) {
329 clk_debug("pll %s set rate=%lu equal to parent rate\n",
330 __clk_get_name(hw->clk), rate);
331 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
334 writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
335 clk_debug("pll %s enter slow mode, set rate OK!\n",
336 __clk_get_name(hw->clk));
340 while(clk_set->rate) {
341 if (clk_set->rate == rate) {
347 if (clk_set->rate == rate) {
348 ret = _pll_clk_set_rate_3188(clk_set, hw);
349 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
352 clk_err("pll %s is no corresponding rate=%lu\n",
353 __clk_get_name(hw->clk), rate);
360 static const struct clk_ops clk_pll_ops_3188 = {
361 .recalc_rate = clk_pll_recalc_rate_3188,
362 .round_rate = clk_pll_round_rate_3188,
363 .set_rate = clk_pll_set_rate_3188,
367 /* CLK_PLL_3188_APLL type ops */
368 static unsigned long clk_pll_recalc_rate_3188_apll(struct clk_hw *hw,
369 unsigned long parent_rate)
371 return clk_pll_recalc_rate_3188(hw, parent_rate);
374 static long clk_pll_round_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
375 unsigned long *prate)
377 struct clk *parent = __clk_get_parent(hw->clk);
379 if (parent && (rate==__clk_get_rate(parent))) {
380 clk_debug("pll %s round rate=%lu equal to parent rate\n",
381 __clk_get_name(hw->clk), rate);
385 return (apll_get_best_set(rate, rk3188_apll_table)->rate);
388 /* 1: use, 0: no use */
389 #define RK3188_USE_ARM_GPLL 1
391 static int clk_pll_set_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
392 unsigned long parent_rate)
394 struct clk_pll *pll = to_clk_pll(hw);
395 struct clk *clk = hw->clk;
396 struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
397 unsigned long arm_gpll_rate;
398 const struct apll_clk_set *ps;
399 u32 old_aclk_div = 0, new_aclk_div = 0;
405 if (rate == parent_rate) {
406 clk_debug("pll %s set rate=%lu equal to parent rate\n",
407 __clk_get_name(hw->clk), rate);
408 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
411 writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
412 clk_debug("pll %s enter slow mode, set rate OK!\n",
413 __clk_get_name(hw->clk));
418 #if !RK3188_USE_ARM_GPLL
422 /* prepare arm_gpll before reparent clk_core to it */
424 clk_err("clk arm_gpll is NULL!\n");
428 /* In rk3188, arm_gpll and cpu_gpll share a same gate,
429 * and aclk_cpu selects cpu_gpll as parent, thus this
430 * gate must keep enabled.
433 if (clk_prepare(arm_gpll)) {
434 clk_err("fail to prepare arm_gpll path\n");
435 clk_unprepare(arm_gpll);
439 if (clk_enable(arm_gpll)) {
440 clk_err("fail to enable arm_gpll path\n");
441 clk_disable(arm_gpll);
442 clk_unprepare(arm_gpll);
447 arm_gpll_rate = __clk_get_rate(arm_gpll);
448 temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
449 temp_div = (temp_div == 0) ? 1 : temp_div;
450 if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
451 clk_debug("temp_div %d > max_div %d\n", temp_div,
452 RK3188_CORE_CLK_MAX_DIV);
453 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
454 __clk_get_rate(clk), arm_gpll_rate);
455 //clk_disable(arm_gpll);
456 //clk_unprepare(arm_gpll);
460 local_irq_save(flags);
462 /* firstly set div, then select arm_gpll path */
463 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
464 RK3188_CRU_CLKSELS_CON(0));
465 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
466 RK3188_CRU_CLKSELS_CON(0));
469 //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
472 local_irq_restore(flags);
474 clk_debug("temp select arm_gpll path, get rate %lu\n",
475 arm_gpll_rate/temp_div);
476 clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
480 ps = apll_get_best_set(rate, rk3188_apll_table);
481 clk_debug("apll will set rate %lu\n", ps->rate);
482 clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
483 ps->pllcon0, ps->pllcon1, ps->pllcon2,
484 ps->clksel0, ps->clksel1);
486 local_irq_save(flags);
488 /* If core src don't select gpll, apll need to enter slow mode
493 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
496 writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
503 writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
504 writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
508 /* PLL power up and wait for locked */
509 writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
512 old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
513 RK3188_CORE_ACLK_MSK);
514 new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
516 if (new_aclk_div >= old_aclk_div) {
517 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
518 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
521 /* PLL return from slow mode */
524 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
526 /* reparent to apll, and set div to 1 */
528 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
529 RK3188_CRU_CLKSELS_CON(0));
530 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
531 RK3188_CRU_CLKSELS_CON(0));
534 if (old_aclk_div > new_aclk_div) {
535 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
536 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
539 //loops_per_jiffy = ps->lpj;
542 local_irq_restore(flags);
546 //clk_disable(arm_gpll);
547 //clk_unprepare(arm_gpll);
550 //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
552 clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
554 readl(pll->reg + RK3188_PLL_CON(0)),
555 readl(pll->reg + RK3188_PLL_CON(1)),
556 readl(pll->reg + RK3188_PLL_CON(2)),
557 readl(pll->reg + RK3188_PLL_CON(3)),
558 cru_readl(RK3188_CRU_CLKSELS_CON(0)),
559 cru_readl(RK3188_CRU_CLKSELS_CON(1)));
564 static const struct clk_ops clk_pll_ops_3188_apll = {
565 .recalc_rate = clk_pll_recalc_rate_3188_apll,
566 .round_rate = clk_pll_round_rate_3188_apll,
567 .set_rate = clk_pll_set_rate_3188_apll,
571 /* CLK_PLL_3188PLUS type ops */
572 static unsigned long clk_pll_recalc_rate_3188plus(struct clk_hw *hw,
573 unsigned long parent_rate)
575 struct clk_pll *pll = to_clk_pll(hw);
579 if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
580 u32 pll_con0 = readl(pll->reg + RK3188_PLL_CON(0));
581 u32 pll_con1 = readl(pll->reg + RK3188_PLL_CON(1));
583 u64 rate64 = (u64)parent_rate * RK3188PLUS_PLL_NF(pll_con1);
585 do_div(rate64, RK3188PLUS_PLL_NR(pll_con0));
586 do_div(rate64, RK3188PLUS_PLL_NO(pll_con0));
592 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
595 clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
600 static long clk_pll_round_rate_3188plus(struct clk_hw *hw, unsigned long rate,
601 unsigned long *prate)
603 return clk_pll_round_rate_3188(hw, rate, prate);
606 static int _pll_clk_set_rate_3188plus(struct pll_clk_set *clk_set,
609 struct clk_pll *pll = to_clk_pll(hw);
610 unsigned long flags = 0;
613 clk_debug("%s start!\n", __func__);
616 spin_lock_irqsave(pll->lock, flags);
619 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
622 writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
624 writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
625 writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
626 writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
631 writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
634 udelay(clk_set->rst_dly);
639 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
642 spin_unlock_irqrestore(pll->lock, flags);
644 clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
645 __clk_get_name(hw->clk),
646 readl(pll->reg + RK3188_PLL_CON(0)),
647 readl(pll->reg + RK3188_PLL_CON(1)),
648 cru_readl(pll->mode_offset));
650 clk_debug("%s end!\n", __func__);
655 static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate,
656 unsigned long parent_rate)
658 //struct clk_pll *pll = to_clk_pll(hw);
659 struct pll_clk_set *clk_set = (struct pll_clk_set *)(pll_com_table);
663 if (rate == parent_rate) {
664 clk_debug("pll %s set rate=%lu equal to parent rate\n",
665 __clk_get_name(hw->clk), rate);
666 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
669 writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
670 clk_debug("pll %s enter slow mode, set rate OK!\n",
671 __clk_get_name(hw->clk));
676 while(clk_set->rate) {
677 if (clk_set->rate == rate) {
683 if (cpu_is_rk3288() && (rate == 297*MHZ)) {
684 if((strncmp(__clk_get_name(hw->clk), "clk_gpll",
685 strlen("clk_gpll")) == 0)) {
687 printk("rk3288 set GPLL BW 20 for HDMI!\n");
688 clk_set->pllcon2 = RK3188_PLL_CLK_BWADJ_SET(20);
692 if (clk_set->rate == rate) {
693 ret = _pll_clk_set_rate_3188plus(clk_set, hw);
694 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
697 clk_err("pll %s is no corresponding rate=%lu\n",
698 __clk_get_name(hw->clk), rate);
705 static const struct clk_ops clk_pll_ops_3188plus = {
706 .recalc_rate = clk_pll_recalc_rate_3188plus,
707 .round_rate = clk_pll_round_rate_3188plus,
708 .set_rate = clk_pll_set_rate_3188plus,
711 /* CLK_PLL_3188PLUS_AUTO type ops */
712 #define PLL_FREF_MIN (269*KHZ)
713 #define PLL_FREF_MAX (2200*MHZ)
715 #define PLL_FVCO_MIN (440*MHZ)
716 #define PLL_FVCO_MAX (2200*MHZ)
718 #define PLL_FOUT_MIN (27500*KHZ)
719 #define PLL_FOUT_MAX (2200*MHZ)
721 #define PLL_NF_MAX (4096)
722 #define PLL_NR_MAX (64)
723 #define PLL_NO_MAX (16)
725 static u32 clk_gcd(u32 numerator, u32 denominator)
729 if (!numerator || !denominator)
731 if (numerator > denominator) {
747 /* FIXME: calc using u64 */
748 static int pll_clk_get_best_set(unsigned long fin_hz, unsigned long fout_hz,
749 u32 *best_nr, u32 *best_nf, u32 *best_no)
751 u32 nr, nf, no, nonr;
752 u32 nr_out, nf_out, no_out;
756 u64 fref, fvco, fout;
760 nr_out = PLL_NR_MAX + 1;
763 // printk("pll_clk_get_set fin=%lu,fout=%lu\n", fin_hz, fout_hz);
764 if(!fin_hz || !fout_hz || fout_hz == fin_hz)
766 gcd_val = clk_gcd(fin_hz, fout_hz);
768 // printk("gcd_val = %d\n",gcd_val);
770 YFfenzi = fout_hz / gcd_val;
771 YFfenmu = fin_hz / gcd_val;
773 // printk("YFfenzi = %d, YFfenmu = %d\n",YFfenzi,YFfenmu);
778 if(nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
780 for(no = 1; no <= PLL_NO_MAX; no++) {
781 if(!(no == 1 || !(no % 2)))
788 if(nr > PLL_NR_MAX) //PLL_NR_MAX
792 if(fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
796 if(fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
799 if(fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
802 /* output all available PLL settings */
803 //printk("nr=%d,\tnf=%d,\tno=%d\n",nr,nf,no);
804 //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr,nf,no);
806 /* select the best from all available PLL settings */
807 if((nr < nr_out) || ((nr == nr_out)&&(no > no_out)))
817 /* output the best PLL setting */
818 if((nr_out <= PLL_NR_MAX) && (no_out > 0)){
819 //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr_out,nf_out,no_out);
820 if(best_nr && best_nf && best_no){
831 static unsigned long clk_pll_recalc_rate_3188plus_auto(struct clk_hw *hw,
832 unsigned long parent_rate)
834 return clk_pll_recalc_rate_3188plus(hw, parent_rate);
837 static long clk_pll_round_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
838 unsigned long *prate)
842 for(best=rate; best>0; best--){
843 if(!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
850 static int clk_pll_set_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
851 unsigned long parent_rate)
855 struct pll_clk_set clk_set;
859 best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
864 pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
866 /* prepare clk_set */
868 clk_set.pllcon0 = RK3188_PLL_CLKR_SET(nr)|RK3188_PLL_CLKOD_SET(no), \
869 clk_set.pllcon1 = RK3188_PLL_CLKF_SET(nf),\
870 clk_set.pllcon2 = RK3188_PLL_CLK_BWADJ_SET(nf >> 1),\
871 clk_set.rst_dly = ((nr*500)/24+1),\
873 ret = _pll_clk_set_rate_3188plus(&clk_set, hw);
874 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk), best);
880 static const struct clk_ops clk_pll_ops_3188plus_auto = {
881 .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
882 .round_rate = clk_pll_round_rate_3188plus_auto,
883 .set_rate = clk_pll_set_rate_3188plus_auto,
887 /* CLK_PLL_3188PLUS_APLL type ops */
888 static unsigned long clk_pll_recalc_rate_3188plus_apll(struct clk_hw *hw,
889 unsigned long parent_rate)
891 return clk_pll_recalc_rate_3188plus(hw, parent_rate);
894 static long clk_pll_round_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
895 unsigned long *prate)
897 return clk_pll_round_rate_3188_apll(hw, rate, prate);
900 /* 1: use, 0: no use */
901 #define RK3188PLUS_USE_ARM_GPLL 1
903 static int clk_pll_set_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
904 unsigned long parent_rate)
906 struct clk_pll *pll = to_clk_pll(hw);
907 struct clk *clk = hw->clk;
908 struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
909 unsigned long arm_gpll_rate;
910 const struct apll_clk_set *ps;
911 u32 old_aclk_div = 0, new_aclk_div = 0;
917 if (rate == parent_rate) {
918 clk_debug("pll %s set rate=%lu equal to parent rate\n",
919 __clk_get_name(hw->clk), rate);
920 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
923 writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
924 clk_debug("pll %s enter slow mode, set rate OK!\n",
925 __clk_get_name(hw->clk));
931 #if !RK3188PLUS_USE_ARM_GPLL
935 /* prepare arm_gpll before reparent clk_core to it */
937 clk_err("clk arm_gpll is NULL!\n");
941 /* In rk3188plus, arm_gpll and cpu_gpll share a same gate,
942 * and aclk_cpu selects cpu_gpll as parent, thus this
943 * gate must keep enabled.
946 if (clk_prepare(arm_gpll)) {
947 clk_err("fail to prepare arm_gpll path\n");
948 clk_unprepare(arm_gpll);
952 if (clk_enable(arm_gpll)) {
953 clk_err("fail to enable arm_gpll path\n");
954 clk_disable(arm_gpll);
955 clk_unprepare(arm_gpll);
960 arm_gpll_rate = __clk_get_rate(arm_gpll);
961 temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
962 temp_div = (temp_div == 0) ? 1 : temp_div;
963 if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
964 clk_debug("temp_div %d > max_div %d\n", temp_div,
965 RK3188_CORE_CLK_MAX_DIV);
966 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
967 __clk_get_rate(clk), arm_gpll_rate);
968 //clk_disable(arm_gpll);
969 //clk_unprepare(arm_gpll);
973 local_irq_save(flags);
975 /* firstly set div, then select arm_gpll path */
976 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
977 RK3188_CRU_CLKSELS_CON(0));
978 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
979 RK3188_CRU_CLKSELS_CON(0));
982 //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
985 local_irq_restore(flags);
987 clk_debug("temp select arm_gpll path, get rate %lu\n",
988 arm_gpll_rate/temp_div);
989 clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
993 ps = apll_get_best_set(rate, rk3188_apll_table);
994 clk_debug("apll will set rate %lu\n", ps->rate);
995 clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
996 ps->pllcon0, ps->pllcon1, ps->pllcon2,
997 ps->clksel0, ps->clksel1);
999 local_irq_save(flags);
1001 /* If core src don't select gpll, apll need to enter slow mode
1006 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1008 /* PLL enter rest */
1009 writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1011 writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1012 writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1013 writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1017 /* return from rest */
1018 writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1021 udelay(ps->rst_dly);
1024 old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
1025 RK3188_CORE_ACLK_MSK);
1026 new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
1028 if (new_aclk_div >= old_aclk_div) {
1029 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1030 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1033 /* PLL return from slow mode */
1036 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1038 /* reparent to apll, and set div to 1 */
1040 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
1041 RK3188_CRU_CLKSELS_CON(0));
1042 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
1043 RK3188_CRU_CLKSELS_CON(0));
1046 if (old_aclk_div > new_aclk_div) {
1047 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1048 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1051 //loops_per_jiffy = ps->lpj;
1054 local_irq_restore(flags);
1058 //clk_disable(arm_gpll);
1059 //clk_unprepare(arm_gpll);
1062 //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1064 clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1066 readl(pll->reg + RK3188_PLL_CON(0)),
1067 readl(pll->reg + RK3188_PLL_CON(1)),
1068 readl(pll->reg + RK3188_PLL_CON(2)),
1069 readl(pll->reg + RK3188_PLL_CON(3)),
1070 cru_readl(RK3188_CRU_CLKSELS_CON(0)),
1071 cru_readl(RK3188_CRU_CLKSELS_CON(1)));
1076 static const struct clk_ops clk_pll_ops_3188plus_apll = {
1077 .recalc_rate = clk_pll_recalc_rate_3188plus_apll,
1078 .round_rate = clk_pll_round_rate_3188plus_apll,
1079 .set_rate = clk_pll_set_rate_3188plus_apll,
1082 /* CLK_PLL_3288_APLL type ops */
1083 static unsigned long clk_pll_recalc_rate_3288_apll(struct clk_hw *hw,
1084 unsigned long parent_rate)
1086 return clk_pll_recalc_rate_3188plus(hw, parent_rate);
1089 static long clk_pll_round_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1090 unsigned long *prate)
1092 struct clk *parent = __clk_get_parent(hw->clk);
1094 if (parent && (rate==__clk_get_rate(parent))) {
1095 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1096 __clk_get_name(hw->clk), rate);
1100 return (apll_get_best_set(rate, rk3288_apll_table)->rate);
1103 /* 1: use, 0: no use */
1104 #define RK3288_USE_ARM_GPLL 1
1106 static int clk_pll_set_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1107 unsigned long parent_rate)
1109 struct clk_pll *pll = to_clk_pll(hw);
1110 struct clk *clk = hw->clk;
1111 struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
1112 unsigned long arm_gpll_rate;
1113 const struct apll_clk_set *ps;
1114 // u32 old_aclk_div = 0, new_aclk_div = 0;
1116 unsigned long flags;
1121 if (rate == parent_rate) {
1122 clk_debug("pll %s set rate=%lu equal to parent rate\n",
1123 __clk_get_name(hw->clk), rate);
1124 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1126 /* pll power down */
1127 writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
1128 clk_debug("pll %s enter slow mode, set rate OK!\n",
1129 __clk_get_name(hw->clk));
1134 #if !RK3288_USE_ARM_GPLL
1138 /* prepare arm_gpll before reparent clk_core to it */
1140 clk_err("clk arm_gpll is NULL!\n");
1144 arm_gpll_rate = __clk_get_rate(arm_gpll);
1145 temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
1146 temp_div = (temp_div == 0) ? 1 : temp_div;
1147 if (temp_div > RK3288_CORE_CLK_MAX_DIV) {
1148 clk_debug("temp_div %d > max_div %d\n", temp_div,
1149 RK3288_CORE_CLK_MAX_DIV);
1150 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1151 __clk_get_rate(clk), arm_gpll_rate);
1156 if (clk_prepare(arm_gpll)) {
1157 clk_err("fail to prepare arm_gpll path\n");
1158 clk_unprepare(arm_gpll);
1162 if (clk_enable(arm_gpll)) {
1163 clk_err("fail to enable arm_gpll path\n");
1164 clk_disable(arm_gpll);
1165 clk_unprepare(arm_gpll);
1170 local_irq_save(flags);
1172 /* firstly set div, then select arm_gpll path */
1173 cru_writel(RK3288_CORE_CLK_DIV(temp_div), RK3288_CRU_CLKSELS_CON(0));
1174 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1175 RK3288_CRU_CLKSELS_CON(0));
1178 //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1181 local_irq_restore(flags);
1183 clk_debug("temp select arm_gpll path, get rate %lu\n",
1184 arm_gpll_rate/temp_div);
1185 clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1189 ps = apll_get_best_set(rate, rk3288_apll_table);
1190 clk_debug("apll will set rate %lu\n", ps->rate);
1191 clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1192 ps->pllcon0, ps->pllcon1, ps->pllcon2,
1193 ps->clksel0, ps->clksel1);
1195 local_irq_save(flags);
1197 /* If core src don't select gpll, apll need to enter slow mode
1202 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1204 /* PLL enter rest */
1205 writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1207 writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1208 writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1209 writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1213 /* return from rest */
1214 writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1217 udelay(ps->rst_dly);
1220 if (rate >= __clk_get_rate(hw->clk)) {
1221 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1222 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1225 /* PLL return from slow mode */
1228 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1230 /* reparent to apll, and set div to 1 */
1232 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1233 RK3288_CRU_CLKSELS_CON(0));
1234 cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1237 if (rate < __clk_get_rate(hw->clk)) {
1238 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1239 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1242 //loops_per_jiffy = ps->lpj;
1245 local_irq_restore(flags);
1249 clk_disable(arm_gpll);
1250 clk_unprepare(arm_gpll);
1253 //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1255 clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1257 readl(pll->reg + RK3188_PLL_CON(0)),
1258 readl(pll->reg + RK3188_PLL_CON(1)),
1259 readl(pll->reg + RK3188_PLL_CON(2)),
1260 readl(pll->reg + RK3188_PLL_CON(3)),
1261 cru_readl(RK3288_CRU_CLKSELS_CON(0)),
1262 cru_readl(RK3288_CRU_CLKSELS_CON(1)));
1268 static const struct clk_ops clk_pll_ops_3288_apll = {
1269 .recalc_rate = clk_pll_recalc_rate_3288_apll,
1270 .round_rate = clk_pll_round_rate_3288_apll,
1271 .set_rate = clk_pll_set_rate_3288_apll,
1276 const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
1278 switch (pll_flags) {
1280 return &clk_pll_ops_3188;
1282 case CLK_PLL_3188_APLL:
1283 return &clk_pll_ops_3188_apll;
1285 case CLK_PLL_3188PLUS:
1286 return &clk_pll_ops_3188plus;
1288 case CLK_PLL_3188PLUS_APLL:
1289 return &clk_pll_ops_3188plus_apll;
1291 case CLK_PLL_3288_APLL:
1292 return &clk_pll_ops_3288_apll;
1294 case CLK_PLL_3188PLUS_AUTO:
1295 return &clk_pll_ops_3188plus_auto;
1298 clk_err("%s: unknown pll_flags!\n", __func__);
1303 struct clk *rk_clk_register_pll(struct device *dev, const char *name,
1304 const char *parent_name, unsigned long flags, void __iomem *reg,
1305 u32 width, u32 mode_offset, u8 mode_shift,
1306 u32 status_offset, u8 status_shift, u32 pll_flags,
1309 struct clk_pll *pll;
1311 struct clk_init_data init;
1314 clk_debug("%s: pll name = %s, pll_flags = 0x%x, register start!\n",
1315 __func__, name, pll_flags);
1317 /* allocate the pll */
1318 pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
1320 clk_err("%s: could not allocate pll clk\n", __func__);
1321 return ERR_PTR(-ENOMEM);
1326 init.parent_names = (parent_name ? &parent_name: NULL);
1327 init.num_parents = (parent_name ? 1 : 0);
1328 init.ops = rk_get_pll_ops(pll_flags);
1330 /* struct clk_pll assignments */
1333 pll->mode_offset = mode_offset;
1334 pll->mode_shift = mode_shift;
1335 pll->status_offset = status_offset;
1336 pll->status_shift = status_shift;
1337 pll->flags = pll_flags;
1339 pll->hw.init = &init;
1341 /* register the clock */
1342 clk = clk_register(dev, &pll->hw);
1347 clk_debug("%s: pll name = %s, pll_flags = 0x%x, register finish!\n",
1348 __func__, name, pll_flags);