1 #include <linux/slab.h>
3 #include <linux/rockchip/cpu.h>
9 static const struct pll_clk_set rk3188_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 pll_clk_set rk3188plus_pll_com_table[] = {
28 _RK3188PLUS_PLL_SET_CLKS(1250000, 12, 625, 1),
29 _RK3188PLUS_PLL_SET_CLKS(1200000, 1, 50, 1),
30 _RK3188PLUS_PLL_SET_CLKS(1188000, 2, 99, 1),
31 _RK3188PLUS_PLL_SET_CLKS(891000, 8, 594, 2),
32 _RK3188PLUS_PLL_SET_CLKS(768000, 1, 64, 2),
33 _RK3188PLUS_PLL_SET_CLKS(594000, 2, 198, 4),
34 _RK3188PLUS_PLL_SET_CLKS(500000, 3, 250, 4),
35 _RK3188PLUS_PLL_SET_CLKS(408000, 1, 68, 4),
36 _RK3188PLUS_PLL_SET_CLKS(396000, 1, 66, 4),
37 _RK3188PLUS_PLL_SET_CLKS(384000, 2, 128, 4),
38 _RK3188PLUS_PLL_SET_CLKS(360000, 1, 60, 4),
39 _RK3188PLUS_PLL_SET_CLKS(300000, 1, 50, 4),
40 _RK3188PLUS_PLL_SET_CLKS(297000, 2, 198, 8),
41 _RK3188PLUS_PLL_SET_CLKS(148500, 2, 99, 8),
42 _RK3188PLUS_PLL_SET_CLKS(0, 0, 0, 0),
45 static const struct apll_clk_set rk3188_apll_table[] = {
46 // (_mhz, nr, nf, no, _periph_div, _aclk_div)
47 _RK3188_APLL_SET_CLKS(2208, 1, 92, 1, 8, 81),
48 _RK3188_APLL_SET_CLKS(2184, 1, 91, 1, 8, 81),
49 _RK3188_APLL_SET_CLKS(2160, 1, 90, 1, 8, 81),
50 _RK3188_APLL_SET_CLKS(2136, 1, 89, 1, 8, 81),
51 _RK3188_APLL_SET_CLKS(2112, 1, 88, 1, 8, 81),
52 _RK3188_APLL_SET_CLKS(2088, 1, 87, 1, 8, 81),
53 _RK3188_APLL_SET_CLKS(2064, 1, 86, 1, 8, 81),
54 _RK3188_APLL_SET_CLKS(2040, 1, 85, 1, 8, 81),
55 _RK3188_APLL_SET_CLKS(2016, 1, 84, 1, 8, 81),
56 _RK3188_APLL_SET_CLKS(1992, 1, 83, 1, 8, 81),
57 _RK3188_APLL_SET_CLKS(1968, 1, 82, 1, 8, 81),
58 _RK3188_APLL_SET_CLKS(1944, 1, 81, 1, 8, 81),
59 _RK3188_APLL_SET_CLKS(1920, 1, 80, 1, 8, 81),
60 _RK3188_APLL_SET_CLKS(1896, 1, 79, 1, 8, 81),
61 _RK3188_APLL_SET_CLKS(1872, 1, 78, 1, 8, 81),
62 _RK3188_APLL_SET_CLKS(1848, 1, 77, 1, 8, 81),
63 _RK3188_APLL_SET_CLKS(1824, 1, 76, 1, 8, 81),
64 _RK3188_APLL_SET_CLKS(1800, 1, 75, 1, 8, 81),
65 _RK3188_APLL_SET_CLKS(1776, 1, 74, 1, 8, 81),
66 _RK3188_APLL_SET_CLKS(1752, 1, 73, 1, 8, 81),
67 _RK3188_APLL_SET_CLKS(1728, 1, 72, 1, 8, 81),
68 _RK3188_APLL_SET_CLKS(1704, 1, 71, 1, 8, 81),
69 _RK3188_APLL_SET_CLKS(1680, 1, 70, 1, 8, 41),
70 _RK3188_APLL_SET_CLKS(1656, 1, 69, 1, 8, 41),
71 _RK3188_APLL_SET_CLKS(1632, 1, 68, 1, 8, 41),
72 _RK3188_APLL_SET_CLKS(1608, 1, 67, 1, 8, 41),
73 _RK3188_APLL_SET_CLKS(1560, 1, 65, 1, 8, 41),
74 _RK3188_APLL_SET_CLKS(1512, 1, 63, 1, 8, 41),
75 _RK3188_APLL_SET_CLKS(1488, 1, 62, 1, 8, 41),
76 _RK3188_APLL_SET_CLKS(1464, 1, 61, 1, 8, 41),
77 _RK3188_APLL_SET_CLKS(1440, 1, 60, 1, 8, 41),
78 _RK3188_APLL_SET_CLKS(1416, 1, 59, 1, 8, 41),
79 _RK3188_APLL_SET_CLKS(1392, 1, 58, 1, 8, 41),
80 _RK3188_APLL_SET_CLKS(1368, 1, 57, 1, 8, 41),
81 _RK3188_APLL_SET_CLKS(1344, 1, 56, 1, 8, 41),
82 _RK3188_APLL_SET_CLKS(1320, 1, 55, 1, 8, 41),
83 _RK3188_APLL_SET_CLKS(1296, 1, 54, 1, 8, 41),
84 _RK3188_APLL_SET_CLKS(1272, 1, 53, 1, 8, 41),
85 _RK3188_APLL_SET_CLKS(1248, 1, 52, 1, 8, 41),
86 _RK3188_APLL_SET_CLKS(1224, 1, 51, 1, 8, 41),
87 _RK3188_APLL_SET_CLKS(1200, 1, 50, 1, 8, 41),
88 _RK3188_APLL_SET_CLKS(1176, 1, 49, 1, 8, 41),
89 _RK3188_APLL_SET_CLKS(1128, 1, 47, 1, 8, 41),
90 _RK3188_APLL_SET_CLKS(1104, 1, 46, 1, 8, 41),
91 _RK3188_APLL_SET_CLKS(1008, 1, 84, 2, 8, 41),
92 _RK3188_APLL_SET_CLKS(912, 1, 76, 2, 8, 41),
93 _RK3188_APLL_SET_CLKS(888, 1, 74, 2, 8, 41),
94 _RK3188_APLL_SET_CLKS(816, 1, 68, 2, 8, 41),
95 _RK3188_APLL_SET_CLKS(792, 1, 66, 2, 8, 41),
96 _RK3188_APLL_SET_CLKS(696, 1, 58, 2, 8, 41),
97 _RK3188_APLL_SET_CLKS(600, 1, 50, 2, 4, 41),
98 _RK3188_APLL_SET_CLKS(552, 1, 92, 4, 4, 41),
99 _RK3188_APLL_SET_CLKS(504, 1, 84, 4, 4, 41),
100 _RK3188_APLL_SET_CLKS(408, 1, 68, 4, 4, 21),
101 _RK3188_APLL_SET_CLKS(312, 1, 52, 4, 2, 21),
102 _RK3188_APLL_SET_CLKS(252, 1, 84, 8, 2, 21),
103 _RK3188_APLL_SET_CLKS(216, 1, 72, 8, 2, 21),
104 _RK3188_APLL_SET_CLKS(126, 1, 84, 16, 2, 11),
105 _RK3188_APLL_SET_CLKS(48, 1, 32, 16, 2, 11),
106 _RK3188_APLL_SET_CLKS(0, 1, 32, 16, 2, 11),
109 static const struct apll_clk_set rk3288_apll_table[] = {
110 // (_mhz, nr, nf, no, l2ram, m0, mp, atclk, pclk_dbg)
111 _RK3288_APLL_SET_CLKS(2208, 1, 92, 1, 2, 2, 4, 4, 4),
112 _RK3288_APLL_SET_CLKS(2184, 1, 91, 1, 2, 2, 4, 4, 4),
113 _RK3288_APLL_SET_CLKS(2160, 1, 90, 1, 2, 2, 4, 4, 4),
114 _RK3288_APLL_SET_CLKS(2136, 1, 89, 1, 2, 2, 4, 4, 4),
115 _RK3288_APLL_SET_CLKS(2112, 1, 88, 1, 2, 2, 4, 4, 4),
116 _RK3288_APLL_SET_CLKS(2088, 1, 87, 1, 2, 2, 4, 4, 4),
117 _RK3288_APLL_SET_CLKS(2064, 1, 86, 1, 2, 2, 4, 4, 4),
118 _RK3288_APLL_SET_CLKS(2040, 1, 85, 1, 2, 2, 4, 4, 4),
119 _RK3288_APLL_SET_CLKS(2016, 1, 84, 1, 2, 2, 4, 4, 4),
120 _RK3288_APLL_SET_CLKS(1992, 1, 83, 1, 2, 2, 4, 4, 4),
121 _RK3288_APLL_SET_CLKS(1968, 1, 82, 1, 2, 2, 4, 4, 4),
122 _RK3288_APLL_SET_CLKS(1944, 1, 81, 1, 2, 2, 4, 4, 4),
123 _RK3288_APLL_SET_CLKS(1920, 1, 80, 1, 2, 2, 4, 4, 4),
124 _RK3288_APLL_SET_CLKS(1896, 1, 79, 1, 2, 2, 4, 4, 4),
125 _RK3288_APLL_SET_CLKS(1872, 1, 78, 1, 2, 2, 4, 4, 4),
126 _RK3288_APLL_SET_CLKS(1848, 1, 77, 1, 2, 2, 4, 4, 4),
127 _RK3288_APLL_SET_CLKS(1824, 1, 76, 1, 2, 2, 4, 4, 4),
128 _RK3288_APLL_SET_CLKS(1800, 1, 75, 1, 2, 2, 4, 4, 4),
129 _RK3288_APLL_SET_CLKS(1776, 1, 74, 1, 2, 2, 4, 4, 4),
130 _RK3288_APLL_SET_CLKS(1752, 1, 73, 1, 2, 2, 4, 4, 4),
131 _RK3288_APLL_SET_CLKS(1728, 1, 72, 1, 2, 2, 4, 4, 4),
132 _RK3288_APLL_SET_CLKS(1704, 1, 71, 1, 2, 2, 4, 4, 4),
133 _RK3288_APLL_SET_CLKS(1680, 1, 70, 1, 2, 2, 4, 4, 4),
134 _RK3288_APLL_SET_CLKS(1656, 1, 69, 1, 2, 2, 4, 4, 4),
135 _RK3288_APLL_SET_CLKS(1632, 1, 68, 1, 2, 2, 4, 4, 4),
136 _RK3288_APLL_SET_CLKS(1608, 1, 67, 1, 2, 2, 4, 4, 4),
137 _RK3288_APLL_SET_CLKS(1560, 1, 65, 1, 2, 2, 4, 4, 4),
138 _RK3288_APLL_SET_CLKS(1512, 1, 63, 1, 2, 2, 4, 4, 4),
139 _RK3288_APLL_SET_CLKS(1488, 1, 62, 1, 2, 2, 4, 4, 4),
140 _RK3288_APLL_SET_CLKS(1464, 1, 61, 1, 2, 2, 4, 4, 4),
141 _RK3288_APLL_SET_CLKS(1440, 1, 60, 1, 2, 2, 4, 4, 4),
142 _RK3288_APLL_SET_CLKS(1416, 1, 59, 1, 2, 2, 4, 4, 4),
143 _RK3288_APLL_SET_CLKS(1392, 1, 58, 1, 2, 2, 4, 4, 4),
144 _RK3288_APLL_SET_CLKS(1368, 1, 57, 1, 2, 2, 4, 4, 4),
145 _RK3288_APLL_SET_CLKS(1344, 1, 56, 1, 2, 2, 4, 4, 4),
146 _RK3288_APLL_SET_CLKS(1320, 1, 55, 1, 2, 2, 4, 4, 4),
147 _RK3288_APLL_SET_CLKS(1296, 1, 54, 1, 2, 2, 4, 4, 4),
148 _RK3288_APLL_SET_CLKS(1272, 1, 53, 1, 2, 2, 4, 4, 4),
149 _RK3288_APLL_SET_CLKS(1248, 1, 52, 1, 2, 2, 4, 4, 4),
150 _RK3288_APLL_SET_CLKS(1224, 1, 51, 1, 2, 2, 4, 4, 4),
151 _RK3288_APLL_SET_CLKS(1200, 1, 50, 1, 2, 2, 4, 4, 4),
152 _RK3288_APLL_SET_CLKS(1176, 1, 49, 1, 2, 2, 4, 4, 4),
153 _RK3288_APLL_SET_CLKS(1128, 1, 47, 1, 2, 2, 4, 4, 4),
154 _RK3288_APLL_SET_CLKS(1104, 1, 46, 1, 2, 2, 4, 4, 4),
155 _RK3288_APLL_SET_CLKS(1008, 1, 84, 2, 2, 2, 4, 4, 4),
156 _RK3288_APLL_SET_CLKS(912, 1, 76, 2, 2, 2, 4, 4, 4),
157 _RK3288_APLL_SET_CLKS(888, 1, 74, 2, 2, 2, 4, 4, 4),
158 _RK3288_APLL_SET_CLKS(816, 1, 68, 2, 2, 2, 4, 4, 4),
159 _RK3288_APLL_SET_CLKS(792, 1, 66, 2, 2, 2, 4, 4, 4),
160 _RK3288_APLL_SET_CLKS(696, 1, 58, 2, 2, 2, 4, 4, 4),
161 _RK3288_APLL_SET_CLKS(672, 1, 56, 2, 2, 2, 4, 4, 4),
162 _RK3288_APLL_SET_CLKS(648, 1, 54, 2, 2, 2, 4, 4, 4),
163 _RK3288_APLL_SET_CLKS(624, 1, 52, 2, 2, 2, 4, 4, 4),
164 _RK3288_APLL_SET_CLKS(600, 1, 50, 2, 2, 2, 4, 4, 4),
165 _RK3288_APLL_SET_CLKS(576, 1, 48, 2, 2, 2, 4, 4, 4),
166 _RK3288_APLL_SET_CLKS(552, 1, 92, 4, 2, 2, 4, 4, 4),
167 _RK3288_APLL_SET_CLKS(528, 1, 88, 4, 2, 2, 4, 4, 4),
168 _RK3288_APLL_SET_CLKS(504, 1, 84, 4, 2, 2, 4, 4, 4),
169 _RK3288_APLL_SET_CLKS(480, 1, 80, 4, 2, 2, 4, 4, 4),
170 _RK3288_APLL_SET_CLKS(456, 1, 76, 4, 2, 2, 4, 4, 4),
171 _RK3288_APLL_SET_CLKS(408, 1, 68, 4, 2, 2, 4, 4, 4),
172 _RK3288_APLL_SET_CLKS(312, 1, 52, 4, 2, 2, 4, 4, 4),
173 _RK3288_APLL_SET_CLKS(252, 1, 84, 8, 2, 2, 4, 4, 4),
174 _RK3288_APLL_SET_CLKS(216, 1, 72, 8, 2, 2, 4, 4, 4),
175 _RK3288_APLL_SET_CLKS(126, 2, 84, 8, 2, 2, 4, 4, 4),
176 _RK3288_APLL_SET_CLKS(48, 2, 32, 8, 2, 2, 4, 4, 4),
177 _RK3288_APLL_SET_CLKS(0, 1, 32, 16, 2, 2, 4, 4, 4),
180 static void pll_wait_lock(struct clk_hw *hw)
182 struct clk_pll *pll = to_clk_pll(hw);
183 int delay = 24000000;
187 if (grf_readl(pll->status_offset) & (1 << pll->status_shift))
193 clk_err("pll %s: can't lock! status_shift=%u\n"
194 "pll_con0=%08x\npll_con1=%08x\n"
195 "pll_con2=%08x\npll_con3=%08x\n",
196 __clk_get_name(hw->clk),
198 cru_readl(pll->reg + RK3188_PLL_CON(0)),
199 cru_readl(pll->reg + RK3188_PLL_CON(1)),
200 cru_readl(pll->reg + RK3188_PLL_CON(2)),
201 cru_readl(pll->reg + RK3188_PLL_CON(3)));
207 /* get rate that is most close to target */
208 static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
209 const struct apll_clk_set *table)
211 const struct apll_clk_set *ps, *pt;
215 if (pt->rate == rate) {
220 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
230 /* get rate that is most close to target */
231 static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
232 const struct pll_clk_set *table)
234 const struct pll_clk_set *ps, *pt;
238 if (pt->rate == rate) {
243 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
253 /* CLK_PLL_3188 type ops */
254 static unsigned long clk_pll_recalc_rate_3188(struct clk_hw *hw,
255 unsigned long parent_rate)
257 struct clk_pll *pll = to_clk_pll(hw);
261 if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
262 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
263 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
265 u64 rate64 = (u64)parent_rate * RK3188_PLL_NF(pll_con1);
267 do_div(rate64, RK3188_PLL_NR(pll_con0));
268 do_div(rate64, RK3188_PLL_NO(pll_con0));
274 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
277 clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
282 static long clk_pll_round_rate_3188(struct clk_hw *hw, unsigned long rate,
283 unsigned long *prate)
285 struct clk *parent = __clk_get_parent(hw->clk);
287 if (parent && (rate==__clk_get_rate(parent))) {
288 clk_debug("pll %s round rate=%lu equal to parent rate\n",
289 __clk_get_name(hw->clk), rate);
293 return (pll_com_get_best_set(rate, rk3188_pll_com_table)->rate);
296 static int _pll_clk_set_rate_3188(struct pll_clk_set *clk_set,
299 struct clk_pll *pll = to_clk_pll(hw);
300 unsigned long flags = 0;
303 clk_debug("%s start!\n", __func__);
306 spin_lock_irqsave(pll->lock, flags);
309 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
311 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
318 cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
319 cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
324 cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
329 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
332 spin_unlock_irqrestore(pll->lock, flags);
334 clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
335 __clk_get_name(hw->clk),
336 cru_readl(pll->reg + RK3188_PLL_CON(0)),
337 cru_readl(pll->reg + RK3188_PLL_CON(1)),
338 cru_readl(pll->mode_offset));
340 clk_debug("%s end!\n", __func__);
345 static int clk_pll_set_rate_3188(struct clk_hw *hw, unsigned long rate,
346 unsigned long parent_rate)
348 struct clk_pll *pll = to_clk_pll(hw);
349 struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188_pll_com_table);
353 if (rate == parent_rate) {
354 clk_debug("pll %s set rate=%lu equal to parent rate\n",
355 __clk_get_name(hw->clk), rate);
356 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
359 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
360 clk_debug("pll %s enter slow mode, set rate OK!\n",
361 __clk_get_name(hw->clk));
365 while(clk_set->rate) {
366 if (clk_set->rate == rate) {
372 if (clk_set->rate == rate) {
373 ret = _pll_clk_set_rate_3188(clk_set, hw);
374 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
377 clk_err("pll %s is no corresponding rate=%lu\n",
378 __clk_get_name(hw->clk), rate);
385 static const struct clk_ops clk_pll_ops_3188 = {
386 .recalc_rate = clk_pll_recalc_rate_3188,
387 .round_rate = clk_pll_round_rate_3188,
388 .set_rate = clk_pll_set_rate_3188,
392 /* CLK_PLL_3188_APLL type ops */
393 static unsigned long clk_pll_recalc_rate_3188_apll(struct clk_hw *hw,
394 unsigned long parent_rate)
396 return clk_pll_recalc_rate_3188(hw, parent_rate);
399 static long clk_pll_round_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
400 unsigned long *prate)
402 struct clk *parent = __clk_get_parent(hw->clk);
404 if (parent && (rate==__clk_get_rate(parent))) {
405 clk_debug("pll %s round rate=%lu equal to parent rate\n",
406 __clk_get_name(hw->clk), rate);
410 return (apll_get_best_set(rate, rk3188_apll_table)->rate);
413 /* 1: use, 0: no use */
414 #define RK3188_USE_ARM_GPLL 1
416 static int clk_pll_set_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
417 unsigned long parent_rate)
419 struct clk_pll *pll = to_clk_pll(hw);
420 struct clk *clk = hw->clk;
421 struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
422 unsigned long arm_gpll_rate;
423 const struct apll_clk_set *ps;
424 u32 old_aclk_div = 0, new_aclk_div = 0;
430 if (rate == parent_rate) {
431 clk_debug("pll %s set rate=%lu equal to parent rate\n",
432 __clk_get_name(hw->clk), rate);
433 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
436 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
437 clk_debug("pll %s enter slow mode, set rate OK!\n",
438 __clk_get_name(hw->clk));
443 #if !RK3188_USE_ARM_GPLL
447 /* prepare arm_gpll before reparent clk_core to it */
449 clk_err("clk arm_gpll is NULL!\n");
453 /* In rk3188, arm_gpll and cpu_gpll share a same gate,
454 * and aclk_cpu selects cpu_gpll as parent, thus this
455 * gate must keep enabled.
458 if (clk_prepare(arm_gpll)) {
459 clk_err("fail to prepare arm_gpll path\n");
460 clk_unprepare(arm_gpll);
464 if (clk_enable(arm_gpll)) {
465 clk_err("fail to enable arm_gpll path\n");
466 clk_disable(arm_gpll);
467 clk_unprepare(arm_gpll);
472 arm_gpll_rate = __clk_get_rate(arm_gpll);
473 temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
474 temp_div = (temp_div == 0) ? 1 : temp_div;
475 if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
476 clk_debug("temp_div %d > max_div %d\n", temp_div,
477 RK3188_CORE_CLK_MAX_DIV);
478 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
479 __clk_get_rate(clk), arm_gpll_rate);
480 //clk_disable(arm_gpll);
481 //clk_unprepare(arm_gpll);
485 local_irq_save(flags);
487 /* firstly set div, then select arm_gpll path */
488 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
489 RK3188_CRU_CLKSELS_CON(0));
490 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
491 RK3188_CRU_CLKSELS_CON(0));
494 //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
497 local_irq_restore(flags);
499 clk_debug("temp select arm_gpll path, get rate %lu\n",
500 arm_gpll_rate/temp_div);
501 clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
505 ps = apll_get_best_set(rate, rk3188_apll_table);
506 clk_debug("apll will set rate %lu\n", ps->rate);
507 clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
508 ps->pllcon0, ps->pllcon1, ps->pllcon2,
509 ps->clksel0, ps->clksel1);
511 local_irq_save(flags);
513 /* If core src don't select gpll, apll need to enter slow mode
518 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
521 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
528 cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
529 cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
533 /* PLL power up and wait for locked */
534 cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
537 old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
538 RK3188_CORE_ACLK_MSK);
539 new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
541 if (new_aclk_div >= old_aclk_div) {
542 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
543 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
546 /* PLL return from slow mode */
549 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
551 /* reparent to apll, and set div to 1 */
553 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
554 RK3188_CRU_CLKSELS_CON(0));
555 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
556 RK3188_CRU_CLKSELS_CON(0));
559 if (old_aclk_div > new_aclk_div) {
560 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
561 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
564 //loops_per_jiffy = ps->lpj;
567 local_irq_restore(flags);
571 //clk_disable(arm_gpll);
572 //clk_unprepare(arm_gpll);
575 //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
577 clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
579 cru_readl(pll->reg + RK3188_PLL_CON(0)),
580 cru_readl(pll->reg + RK3188_PLL_CON(1)),
581 cru_readl(pll->reg + RK3188_PLL_CON(2)),
582 cru_readl(pll->reg + RK3188_PLL_CON(3)),
583 cru_readl(RK3188_CRU_CLKSELS_CON(0)),
584 cru_readl(RK3188_CRU_CLKSELS_CON(1)));
589 static const struct clk_ops clk_pll_ops_3188_apll = {
590 .recalc_rate = clk_pll_recalc_rate_3188_apll,
591 .round_rate = clk_pll_round_rate_3188_apll,
592 .set_rate = clk_pll_set_rate_3188_apll,
596 /* CLK_PLL_3188PLUS type ops */
597 static unsigned long clk_pll_recalc_rate_3188plus(struct clk_hw *hw,
598 unsigned long parent_rate)
600 struct clk_pll *pll = to_clk_pll(hw);
604 if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
605 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
606 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
608 u64 rate64 = (u64)parent_rate * RK3188PLUS_PLL_NF(pll_con1);
610 do_div(rate64, RK3188PLUS_PLL_NR(pll_con0));
611 do_div(rate64, RK3188PLUS_PLL_NO(pll_con0));
617 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
620 clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
625 static long clk_pll_round_rate_3188plus(struct clk_hw *hw, unsigned long rate,
626 unsigned long *prate)
628 struct clk *parent = __clk_get_parent(hw->clk);
630 if (parent && (rate==__clk_get_rate(parent))) {
631 clk_debug("pll %s round rate=%lu equal to parent rate\n",
632 __clk_get_name(hw->clk), rate);
636 return (pll_com_get_best_set(rate, rk3188plus_pll_com_table)->rate);
639 static int _pll_clk_set_rate_3188plus(struct pll_clk_set *clk_set,
642 struct clk_pll *pll = to_clk_pll(hw);
643 unsigned long flags = 0;
646 clk_debug("%s start!\n", __func__);
649 spin_lock_irqsave(pll->lock, flags);
652 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
655 cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
657 cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
658 cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
659 cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
664 cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
667 udelay(clk_set->rst_dly);
672 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
675 spin_unlock_irqrestore(pll->lock, flags);
677 clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
678 __clk_get_name(hw->clk),
679 cru_readl(pll->reg + RK3188_PLL_CON(0)),
680 cru_readl(pll->reg + RK3188_PLL_CON(1)),
681 cru_readl(pll->mode_offset));
683 clk_debug("%s end!\n", __func__);
688 static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate,
689 unsigned long parent_rate)
691 //struct clk_pll *pll = to_clk_pll(hw);
692 struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188plus_pll_com_table);
696 if (rate == parent_rate) {
697 clk_debug("pll %s set rate=%lu equal to parent rate\n",
698 __clk_get_name(hw->clk), rate);
699 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
702 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
703 clk_debug("pll %s enter slow mode, set rate OK!\n",
704 __clk_get_name(hw->clk));
709 while(clk_set->rate) {
710 if (clk_set->rate == rate) {
716 if (cpu_is_rk3288() && (rate == 297*MHZ)) {
717 if((strncmp(__clk_get_name(hw->clk), "clk_gpll",
718 strlen("clk_gpll")) == 0)) {
720 printk("rk3288 set GPLL BW 20 for HDMI!\n");
721 clk_set->pllcon2 = RK3188_PLL_CLK_BWADJ_SET(20);
725 if (clk_set->rate == rate) {
726 ret = _pll_clk_set_rate_3188plus(clk_set, hw);
727 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
730 clk_err("pll %s is no corresponding rate=%lu\n",
731 __clk_get_name(hw->clk), rate);
738 static const struct clk_ops clk_pll_ops_3188plus = {
739 .recalc_rate = clk_pll_recalc_rate_3188plus,
740 .round_rate = clk_pll_round_rate_3188plus,
741 .set_rate = clk_pll_set_rate_3188plus,
744 /* CLK_PLL_3188PLUS_AUTO type ops */
745 #define PLL_FREF_MIN (269*KHZ)
746 #define PLL_FREF_MAX (2200*MHZ)
748 #define PLL_FVCO_MIN (440*MHZ)
749 #define PLL_FVCO_MAX (2200*MHZ)
751 #define PLL_FOUT_MIN (27500*KHZ)
752 #define PLL_FOUT_MAX (2200*MHZ)
754 #define PLL_NF_MAX (4096)
755 #define PLL_NR_MAX (64)
756 #define PLL_NO_MAX (16)
758 static u32 clk_gcd(u32 numerator, u32 denominator)
762 if (!numerator || !denominator)
764 if (numerator > denominator) {
780 /* FIXME: calc using u64 */
781 static int pll_clk_get_best_set(unsigned long fin_hz, unsigned long fout_hz,
782 u32 *best_nr, u32 *best_nf, u32 *best_no)
784 u32 nr, nf, no, nonr;
785 u32 nr_out, nf_out, no_out;
789 u64 fref, fvco, fout;
793 nr_out = PLL_NR_MAX + 1;
796 // printk("pll_clk_get_set fin=%lu,fout=%lu\n", fin_hz, fout_hz);
797 if(!fin_hz || !fout_hz || fout_hz == fin_hz)
799 gcd_val = clk_gcd(fin_hz, fout_hz);
801 // printk("gcd_val = %d\n",gcd_val);
803 YFfenzi = fout_hz / gcd_val;
804 YFfenmu = fin_hz / gcd_val;
806 // printk("YFfenzi = %d, YFfenmu = %d\n",YFfenzi,YFfenmu);
811 if(nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
813 for(no = 1; no <= PLL_NO_MAX; no++) {
814 if(!(no == 1 || !(no % 2)))
821 if(nr > PLL_NR_MAX) //PLL_NR_MAX
825 if(fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
829 if(fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
832 if(fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
835 /* output all available PLL settings */
836 //printk("nr=%d,\tnf=%d,\tno=%d\n",nr,nf,no);
837 //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr,nf,no);
839 /* select the best from all available PLL settings */
840 if((nr < nr_out) || ((nr == nr_out)&&(no > no_out)))
850 /* output the best PLL setting */
851 if((nr_out <= PLL_NR_MAX) && (no_out > 0)){
852 //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr_out,nf_out,no_out);
853 if(best_nr && best_nf && best_no){
864 static unsigned long clk_pll_recalc_rate_3188plus_auto(struct clk_hw *hw,
865 unsigned long parent_rate)
867 return clk_pll_recalc_rate_3188plus(hw, parent_rate);
870 static long clk_pll_round_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
871 unsigned long *prate)
875 for(best=rate; best>0; best--){
876 if(!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
883 static int clk_pll_set_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
884 unsigned long parent_rate)
888 struct pll_clk_set clk_set;
892 best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
897 pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
899 /* prepare clk_set */
901 clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
902 clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
903 clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
904 clk_set.rst_dly = ((nr*500)/24+1);
906 ret = _pll_clk_set_rate_3188plus(&clk_set, hw);
907 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk), best);
913 static const struct clk_ops clk_pll_ops_3188plus_auto = {
914 .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
915 .round_rate = clk_pll_round_rate_3188plus_auto,
916 .set_rate = clk_pll_set_rate_3188plus_auto,
920 /* CLK_PLL_3188PLUS_APLL type ops */
921 static unsigned long clk_pll_recalc_rate_3188plus_apll(struct clk_hw *hw,
922 unsigned long parent_rate)
924 return clk_pll_recalc_rate_3188plus(hw, parent_rate);
927 static long clk_pll_round_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
928 unsigned long *prate)
930 return clk_pll_round_rate_3188_apll(hw, rate, prate);
933 /* 1: use, 0: no use */
934 #define RK3188PLUS_USE_ARM_GPLL 1
936 static int clk_pll_set_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
937 unsigned long parent_rate)
939 struct clk_pll *pll = to_clk_pll(hw);
940 struct clk *clk = hw->clk;
941 struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
942 unsigned long arm_gpll_rate;
943 const struct apll_clk_set *ps;
944 u32 old_aclk_div = 0, new_aclk_div = 0;
950 if (rate == parent_rate) {
951 clk_debug("pll %s set rate=%lu equal to parent rate\n",
952 __clk_get_name(hw->clk), rate);
953 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
956 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
957 clk_debug("pll %s enter slow mode, set rate OK!\n",
958 __clk_get_name(hw->clk));
964 #if !RK3188PLUS_USE_ARM_GPLL
968 /* prepare arm_gpll before reparent clk_core to it */
970 clk_err("clk arm_gpll is NULL!\n");
974 /* In rk3188plus, arm_gpll and cpu_gpll share a same gate,
975 * and aclk_cpu selects cpu_gpll as parent, thus this
976 * gate must keep enabled.
979 if (clk_prepare(arm_gpll)) {
980 clk_err("fail to prepare arm_gpll path\n");
981 clk_unprepare(arm_gpll);
985 if (clk_enable(arm_gpll)) {
986 clk_err("fail to enable arm_gpll path\n");
987 clk_disable(arm_gpll);
988 clk_unprepare(arm_gpll);
993 arm_gpll_rate = __clk_get_rate(arm_gpll);
994 temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
995 temp_div = (temp_div == 0) ? 1 : temp_div;
996 if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
997 clk_debug("temp_div %d > max_div %d\n", temp_div,
998 RK3188_CORE_CLK_MAX_DIV);
999 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1000 __clk_get_rate(clk), arm_gpll_rate);
1001 //clk_disable(arm_gpll);
1002 //clk_unprepare(arm_gpll);
1006 local_irq_save(flags);
1008 /* firstly set div, then select arm_gpll path */
1009 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
1010 RK3188_CRU_CLKSELS_CON(0));
1011 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
1012 RK3188_CRU_CLKSELS_CON(0));
1015 //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1018 local_irq_restore(flags);
1020 clk_debug("temp select arm_gpll path, get rate %lu\n",
1021 arm_gpll_rate/temp_div);
1022 clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1026 ps = apll_get_best_set(rate, rk3188_apll_table);
1027 clk_debug("apll will set rate %lu\n", ps->rate);
1028 clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1029 ps->pllcon0, ps->pllcon1, ps->pllcon2,
1030 ps->clksel0, ps->clksel1);
1032 local_irq_save(flags);
1034 /* If core src don't select gpll, apll need to enter slow mode
1039 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1041 /* PLL enter rest */
1042 cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1044 cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1045 cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1046 cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1050 /* return from rest */
1051 cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1054 udelay(ps->rst_dly);
1057 old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
1058 RK3188_CORE_ACLK_MSK);
1059 new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
1061 if (new_aclk_div >= old_aclk_div) {
1062 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1063 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1066 /* PLL return from slow mode */
1069 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1071 /* reparent to apll, and set div to 1 */
1073 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
1074 RK3188_CRU_CLKSELS_CON(0));
1075 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
1076 RK3188_CRU_CLKSELS_CON(0));
1079 if (old_aclk_div > new_aclk_div) {
1080 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1081 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1084 //loops_per_jiffy = ps->lpj;
1087 local_irq_restore(flags);
1091 //clk_disable(arm_gpll);
1092 //clk_unprepare(arm_gpll);
1095 //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1097 clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1099 cru_readl(pll->reg + RK3188_PLL_CON(0)),
1100 cru_readl(pll->reg + RK3188_PLL_CON(1)),
1101 cru_readl(pll->reg + RK3188_PLL_CON(2)),
1102 cru_readl(pll->reg + RK3188_PLL_CON(3)),
1103 cru_readl(RK3188_CRU_CLKSELS_CON(0)),
1104 cru_readl(RK3188_CRU_CLKSELS_CON(1)));
1109 static const struct clk_ops clk_pll_ops_3188plus_apll = {
1110 .recalc_rate = clk_pll_recalc_rate_3188plus_apll,
1111 .round_rate = clk_pll_round_rate_3188plus_apll,
1112 .set_rate = clk_pll_set_rate_3188plus_apll,
1115 /* CLK_PLL_3288_APLL type ops */
1116 static unsigned long clk_pll_recalc_rate_3288_apll(struct clk_hw *hw,
1117 unsigned long parent_rate)
1119 return clk_pll_recalc_rate_3188plus(hw, parent_rate);
1122 static long clk_pll_round_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1123 unsigned long *prate)
1125 struct clk *parent = __clk_get_parent(hw->clk);
1127 if (parent && (rate==__clk_get_rate(parent))) {
1128 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1129 __clk_get_name(hw->clk), rate);
1133 return (apll_get_best_set(rate, rk3288_apll_table)->rate);
1136 /* 1: use, 0: no use */
1137 #define RK3288_USE_ARM_GPLL 1
1139 static int clk_pll_set_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1140 unsigned long parent_rate)
1142 struct clk_pll *pll = to_clk_pll(hw);
1143 struct clk *clk = hw->clk;
1144 struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
1145 unsigned long arm_gpll_rate, temp_rate, old_rate;
1146 const struct apll_clk_set *ps;
1147 // u32 old_aclk_div = 0, new_aclk_div = 0;
1149 unsigned long flags;
1154 if (rate == parent_rate) {
1155 clk_debug("pll %s set rate=%lu equal to parent rate\n",
1156 __clk_get_name(hw->clk), rate);
1157 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1159 /* pll power down */
1160 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
1161 clk_debug("pll %s enter slow mode, set rate OK!\n",
1162 __clk_get_name(hw->clk));
1167 #if !RK3288_USE_ARM_GPLL
1171 /* prepare arm_gpll before reparent clk_core to it */
1173 clk_err("clk arm_gpll is NULL!\n");
1177 arm_gpll_rate = __clk_get_rate(arm_gpll);
1178 old_rate = __clk_get_rate(clk);
1180 temp_rate = (old_rate > rate) ? old_rate : rate;
1181 temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
1183 if (temp_div > RK3288_CORE_CLK_MAX_DIV) {
1184 clk_debug("temp_div %d > max_div %d\n", temp_div,
1185 RK3288_CORE_CLK_MAX_DIV);
1186 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1187 __clk_get_rate(clk), arm_gpll_rate);
1192 if (clk_prepare(arm_gpll)) {
1193 clk_err("fail to prepare arm_gpll path\n");
1194 clk_unprepare(arm_gpll);
1198 if (clk_enable(arm_gpll)) {
1199 clk_err("fail to enable arm_gpll path\n");
1200 clk_disable(arm_gpll);
1201 clk_unprepare(arm_gpll);
1206 local_irq_save(flags);
1209 if (temp_div == 1) {
1210 /* when old_rate/2 < (old_rate-arm_gpll_rate),
1211 we can set div to make rate change more gently */
1212 if (old_rate > (2*arm_gpll_rate)) {
1213 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1215 cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
1217 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1218 RK3288_CRU_CLKSELS_CON(0));
1220 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1222 cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1224 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1225 RK3288_CRU_CLKSELS_CON(0));
1228 cru_writel(RK3288_CORE_CLK_DIV(temp_div), RK3288_CRU_CLKSELS_CON(0));
1229 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1230 RK3288_CRU_CLKSELS_CON(0));
1234 //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1237 local_irq_restore(flags);
1239 clk_debug("temp select arm_gpll path, get rate %lu\n",
1240 arm_gpll_rate/temp_div);
1241 clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1245 ps = apll_get_best_set(rate, rk3288_apll_table);
1246 clk_debug("apll will set rate %lu\n", ps->rate);
1247 clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1248 ps->pllcon0, ps->pllcon1, ps->pllcon2,
1249 ps->clksel0, ps->clksel1);
1251 local_irq_save(flags);
1253 /* If core src don't select gpll, apll need to enter slow mode
1258 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1260 /* PLL enter rest */
1261 cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1263 cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1264 cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1265 cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1269 /* return from rest */
1270 cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1273 udelay(ps->rst_dly);
1276 if (rate >= __clk_get_rate(hw->clk)) {
1277 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1278 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1281 /* PLL return from slow mode */
1284 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1286 /* reparent to apll, and set div to 1 */
1288 if (temp_div == 1) {
1289 /* when rate/2 < (old_rate-arm_gpll_rate),
1290 we can set div to make rate change more gently */
1291 if (rate > (2*arm_gpll_rate)) {
1292 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1294 cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
1296 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1297 RK3288_CRU_CLKSELS_CON(0));
1299 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1301 cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1303 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1304 RK3288_CRU_CLKSELS_CON(0));
1307 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1308 RK3288_CRU_CLKSELS_CON(0));
1309 cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1313 if (rate < __clk_get_rate(hw->clk)) {
1314 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1315 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1318 //loops_per_jiffy = ps->lpj;
1321 local_irq_restore(flags);
1325 //clk_disable(arm_gpll);
1326 //clk_unprepare(arm_gpll);
1329 //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1331 clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1333 cru_readl(pll->reg + RK3188_PLL_CON(0)),
1334 cru_readl(pll->reg + RK3188_PLL_CON(1)),
1335 cru_readl(pll->reg + RK3188_PLL_CON(2)),
1336 cru_readl(pll->reg + RK3188_PLL_CON(3)),
1337 cru_readl(RK3288_CRU_CLKSELS_CON(0)),
1338 cru_readl(RK3288_CRU_CLKSELS_CON(1)));
1344 static const struct clk_ops clk_pll_ops_3288_apll = {
1345 .recalc_rate = clk_pll_recalc_rate_3288_apll,
1346 .round_rate = clk_pll_round_rate_3288_apll,
1347 .set_rate = clk_pll_set_rate_3288_apll,
1352 const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
1354 switch (pll_flags) {
1356 return &clk_pll_ops_3188;
1358 case CLK_PLL_3188_APLL:
1359 return &clk_pll_ops_3188_apll;
1361 case CLK_PLL_3188PLUS:
1362 return &clk_pll_ops_3188plus;
1364 case CLK_PLL_3188PLUS_APLL:
1365 return &clk_pll_ops_3188plus_apll;
1367 case CLK_PLL_3288_APLL:
1368 return &clk_pll_ops_3288_apll;
1370 case CLK_PLL_3188PLUS_AUTO:
1371 return &clk_pll_ops_3188plus_auto;
1374 clk_err("%s: unknown pll_flags!\n", __func__);
1379 struct clk *rk_clk_register_pll(struct device *dev, const char *name,
1380 const char *parent_name, unsigned long flags, u32 reg,
1381 u32 width, u32 mode_offset, u8 mode_shift,
1382 u32 status_offset, u8 status_shift, u32 pll_flags,
1385 struct clk_pll *pll;
1387 struct clk_init_data init;
1390 clk_debug("%s: pll name = %s, pll_flags = 0x%x, register start!\n",
1391 __func__, name, pll_flags);
1393 /* allocate the pll */
1394 pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
1396 clk_err("%s: could not allocate pll clk\n", __func__);
1397 return ERR_PTR(-ENOMEM);
1402 init.parent_names = (parent_name ? &parent_name: NULL);
1403 init.num_parents = (parent_name ? 1 : 0);
1404 init.ops = rk_get_pll_ops(pll_flags);
1406 /* struct clk_pll assignments */
1409 pll->mode_offset = mode_offset;
1410 pll->mode_shift = mode_shift;
1411 pll->status_offset = status_offset;
1412 pll->status_shift = status_shift;
1413 pll->flags = pll_flags;
1415 pll->hw.init = &init;
1417 /* register the clock */
1418 clk = clk_register(dev, &pll->hw);
1423 clk_debug("%s: pll name = %s, pll_flags = 0x%x, register finish!\n",
1424 __func__, name, pll_flags);