clk: rk: change clk_core init-rate and the way to get cru&grf base
[firefly-linux-kernel-4.4.55.git] / drivers / clk / rockchip / clk-pll.c
1 #include <linux/slab.h>
2 #include <asm/io.h>
3
4 #include "clk-ops.h"
5 #include "clk-pll.h"
6
7
8
9 //static unsigned long lpj_gpll;
10
11 #define PLLS_IN_NORM(pll_id) (((cru_readl(CRU_MODE_CON)&PLL_MODE_MSK(pll_id))\
12                         ==(PLL_MODE_NORM(pll_id)&PLL_MODE_MSK(pll_id)))\
13                 &&!(cru_readl(PLL_CONS(pll_id,3))&PLL_BYPASS))
14
15
16 static const struct apll_clk_set apll_table[] = {
17         //            (_mhz,    nr,     nf,     no,     _periph_div,    _aclk_div)
18         _APLL_SET_CLKS(2208,    1,      92,     1,      8,      81),
19         _APLL_SET_CLKS(2184,    1,      91,     1,      8,      81),
20         _APLL_SET_CLKS(2160,    1,      90,     1,      8,      81),
21         _APLL_SET_CLKS(2136,    1,      89,     1,      8,      81),
22         _APLL_SET_CLKS(2112,    1,      88,     1,      8,      81),
23         _APLL_SET_CLKS(2088,    1,      87,     1,      8,      81),
24         _APLL_SET_CLKS(2064,    1,      86,     1,      8,      81),
25         _APLL_SET_CLKS(2040,    1,      85,     1,      8,      81),
26         _APLL_SET_CLKS(2016,    1,      84,     1,      8,      81),
27         _APLL_SET_CLKS(1992,    1,      83,     1,      8,      81),
28         _APLL_SET_CLKS(1968,    1,      82,     1,      8,      81),
29         _APLL_SET_CLKS(1944,    1,      81,     1,      8,      81),
30         _APLL_SET_CLKS(1920,    1,      80,     1,      8,      81),
31         _APLL_SET_CLKS(1896,    1,      79,     1,      8,      81),
32         _APLL_SET_CLKS(1872,    1,      78,     1,      8,      81),
33         _APLL_SET_CLKS(1848,    1,      77,     1,      8,      81),
34         _APLL_SET_CLKS(1824,    1,      76,     1,      8,      81),
35         _APLL_SET_CLKS(1800,    1,      75,     1,      8,      81),
36         _APLL_SET_CLKS(1776,    1,      74,     1,      8,      81),
37         _APLL_SET_CLKS(1752,    1,      73,     1,      8,      81),
38         _APLL_SET_CLKS(1728,    1,      72,     1,      8,      81),
39         _APLL_SET_CLKS(1704,    1,      71,     1,      8,      81),
40         _APLL_SET_CLKS(1680,    1,      70,     1,      8,      41),
41         _APLL_SET_CLKS(1656,    1,      69,     1,      8,      41),
42         _APLL_SET_CLKS(1632,    1,      68,     1,      8,      41),
43         _APLL_SET_CLKS(1608,    1,      67,     1,      8,      41),
44         _APLL_SET_CLKS(1560,    1,      65,     1,      8,      41),
45         _APLL_SET_CLKS(1512,    1,      63,     1,      8,      41),
46         _APLL_SET_CLKS(1488,    1,      62,     1,      8,      41),
47         _APLL_SET_CLKS(1464,    1,      61,     1,      8,      41),
48         _APLL_SET_CLKS(1440,    1,      60,     1,      8,      41),
49         _APLL_SET_CLKS(1416,    1,      59,     1,      8,      41),
50         _APLL_SET_CLKS(1392,    1,      58,     1,      8,      41),
51         _APLL_SET_CLKS(1368,    1,      57,     1,      8,      41),
52         _APLL_SET_CLKS(1344,    1,      56,     1,      8,      41),
53         _APLL_SET_CLKS(1320,    1,      55,     1,      8,      41),
54         _APLL_SET_CLKS(1296,    1,      54,     1,      8,      41),
55         _APLL_SET_CLKS(1272,    1,      53,     1,      8,      41),
56         _APLL_SET_CLKS(1248,    1,      52,     1,      8,      41),
57         _APLL_SET_CLKS(1224,    1,      51,     1,      8,      41),
58         _APLL_SET_CLKS(1200,    1,      50,     1,      8,      41),
59         _APLL_SET_CLKS(1176,    1,      49,     1,      8,      41),
60         _APLL_SET_CLKS(1128,    1,      47,     1,      8,      41),
61         _APLL_SET_CLKS(1104,    1,      46,     1,      8,      41),
62         _APLL_SET_CLKS(1008,    1,      84,     2,      8,      41),
63         _APLL_SET_CLKS(912,     1,      76,     2,      8,      41),
64         _APLL_SET_CLKS(888,     1,      74,     2,      8,      41),
65         _APLL_SET_CLKS(816,     1,      68,     2,      8,      41),
66         _APLL_SET_CLKS(792,     1,      66,     2,      8,      41),
67         _APLL_SET_CLKS(696,     1,      58,     2,      8,      41),
68         _APLL_SET_CLKS(600,     1,      50,     2,      4,      41),
69         _APLL_SET_CLKS(552,     1,      92,     4,      4,      41),
70         _APLL_SET_CLKS(504,     1,      84,     4,      4,      41),
71         _APLL_SET_CLKS(408,     1,      68,     4,      4,      21),
72         _APLL_SET_CLKS(312,     1,      52,     4,      2,      21),
73         _APLL_SET_CLKS(252,     1,      84,     8,      2,      21),
74         _APLL_SET_CLKS(216,     1,      72,     8,      2,      21),
75         _APLL_SET_CLKS(126,     1,      84,     16,     2,      11),
76         _APLL_SET_CLKS(48,      1,      32,     16,     2,      11),
77         _APLL_SET_CLKS(0,       1,      32,     16,     2,      11),
78 };
79
80 static const struct pll_clk_set pll_com_table[] = {
81         _PLL_SET_CLKS(1200000,  1,      50,     1),
82         _PLL_SET_CLKS(1188000,  2,      99,     1),
83         _PLL_SET_CLKS(891000,   8,      594,    2),
84         _PLL_SET_CLKS(768000,   1,      64,     2),
85         _PLL_SET_CLKS(594000,   2,      198,    4),
86         _PLL_SET_CLKS(408000,   1,      68,     4),
87         _PLL_SET_CLKS(384000,   2,      128,    4),
88         _PLL_SET_CLKS(360000,   1,      60,     4),
89         _PLL_SET_CLKS(300000,   1,      50,     4),
90         _PLL_SET_CLKS(297000,   2,      198,    8),
91         _PLL_SET_CLKS(148500,   2,      99,     8),
92         _PLL_SET_CLKS(0,        0,      0,      0),
93 };
94
95 static void pll_wait_lock(int pll_idx)
96 {
97         u32 pll_state[4] = {1, 0, 2, 3};
98         u32 bit = 0x20u << pll_state[pll_idx];
99         int delay = 24000000;
100         while (delay > 0) {
101                 if (grf_readl(RK3188_GRF_SOC_STATUS0) & bit)
102                         break;
103                 delay--;
104         }
105         
106         if (delay == 0) {
107                 clk_err("PLL_ID=%d\npll_con0=%08x\npll_con1=%08x\n"
108                                 "pll_con2=%08x\npll_con3=%08x\n",
109                                 pll_idx,
110                                 cru_readl(PLL_CONS(pll_idx, 0)),
111                                 cru_readl(PLL_CONS(pll_idx, 1)),
112                                 cru_readl(PLL_CONS(pll_idx, 2)),
113                                 cru_readl(PLL_CONS(pll_idx, 3)));
114
115                 clk_err("wait pll bit 0x%x time out!\n", bit);
116                 while(1);
117         }
118 }
119
120
121 /* recalc_rate */
122 static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
123                 unsigned long parent_rate)
124 {
125         struct clk_pll *pll = to_clk_pll(hw);
126         u8 pll_id = pll->id;
127         unsigned long rate;
128
129         if (PLLS_IN_NORM(pll_id)) {
130                 u32 pll_con0 = cru_readl(PLL_CONS(pll_id, 0));
131                 u32 pll_con1 = cru_readl(PLL_CONS(pll_id, 1));
132
133                 u64 rate64 = (u64)parent_rate * PLL_NF(pll_con1);
134
135                 do_div(rate64, PLL_NR(pll_con0));
136                 do_div(rate64, PLL_NO(pll_con0));
137
138                 rate = rate64;
139         } else {
140                 rate = parent_rate;
141                 clk_debug("pll id=%d  slow mode\n", pll_id);
142         }
143
144         clk_debug("pll id=%d, recalc rate =%lu\n", pll->id, rate);
145
146         return rate;
147 }
148
149 /* round_rate */
150 /* get rate that is most close to target */
151 static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
152                 const struct apll_clk_set *table)
153 {
154         const struct apll_clk_set *ps, *pt;
155
156         ps = pt = table;
157         while (pt->rate) {
158                 if (pt->rate == rate) {
159                         ps = pt;
160                         break;
161                 }
162
163                 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
164                         ps = pt;
165                 if (pt->rate < rate)
166                         break;
167                 pt++;
168         }
169
170         return ps;
171 }
172
173 /* get rate that is most close to target */
174 static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
175                 const struct pll_clk_set *table)
176 {
177         const struct pll_clk_set *ps, *pt;
178
179         ps = pt = table;
180         while (pt->rate) {
181                 if (pt->rate == rate) {
182                         ps = pt;
183                         break;
184                 }
185
186                 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
187                         ps = pt;
188                 if (pt->rate < rate)
189                         break;
190                 pt++;
191         }
192
193         return ps;
194 }
195
196 static long clk_apll_round_rate(struct clk_hw *hw, unsigned long rate,
197                 unsigned long *prate)
198 {
199         return (apll_get_best_set(rate, apll_table)->rate);
200 }
201
202 static long clk_pll_com_round_rate(struct clk_hw *hw, unsigned long rate,
203                 unsigned long *prate)
204 {
205         return (pll_com_get_best_set(rate, pll_com_table)->rate);
206 }
207
208 static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
209                 unsigned long *prate)
210 {
211         struct clk_pll *pll = to_clk_pll(hw);
212         struct clk *parent = __clk_get_parent(hw->clk);
213         long rate_out = 0;
214
215         if (parent && (rate==__clk_get_rate(parent))) {
216                 clk_debug("pll id=%d round rate=%lu equal to parent rate\n",
217                                 pll->id, rate);
218                 return rate;
219         }
220
221         switch (pll->id){
222                 case APLL_ID: {
223                                       rate_out = clk_apll_round_rate(hw, rate, prate);
224                                       break;
225                               }
226                 default: {
227                                  rate_out = clk_pll_com_round_rate(hw, rate, prate);
228                                  break;
229                          }
230         }
231
232         return rate_out;
233 }
234
235 /* set_rate */
236 static int _pll_clk_set_rate(struct pll_clk_set *clk_set, u8 pll_id,
237                 spinlock_t *lock)
238 {
239         unsigned long flags = 0;
240
241
242         clk_debug("_pll_clk_set_rate start!\n");
243
244         if(lock)
245                 spin_lock_irqsave(lock, flags);
246
247         //enter slowmode
248         cru_writel(PLL_MODE_SLOW(pll_id), CRU_MODE_CON);
249         cru_writel((0x1<<(16+1))|(0x1<<1), PLL_CONS(pll_id, 3));
250         dsb();
251         dsb();
252         dsb();
253         dsb();
254         dsb();
255         dsb();
256         cru_writel(clk_set->pllcon0, PLL_CONS(pll_id, 0));
257         cru_writel(clk_set->pllcon1, PLL_CONS(pll_id, 1));
258
259         rk30_clock_udelay(1);
260
261         cru_writel((0x1<<(16+1)), PLL_CONS(pll_id, 3));
262
263         pll_wait_lock(pll_id);
264
265         //return from slow
266         cru_writel(PLL_MODE_NORM(pll_id), CRU_MODE_CON);
267
268         if (lock)
269                 spin_unlock_irqrestore(lock, flags);
270
271         clk_debug("pll id=%d, dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
272                         pll_id,
273                         cru_readl(PLL_CONS(pll_id,0)),
274                         cru_readl(PLL_CONS(pll_id,1)),
275                         cru_readl(CRU_MODE_CON));
276
277         clk_debug("_pll_clk_set_rate end!\n");
278
279         return 0;
280 }
281
282 static int clk_pll_com_set_rate(struct clk_hw *hw, unsigned long rate,
283                 unsigned long parent_rate)
284 {
285         struct clk_pll *pll = to_clk_pll(hw);
286         struct pll_clk_set *clk_set = (struct pll_clk_set *)(pll_com_table);
287         int ret = 0;
288
289
290         if (rate == parent_rate) {
291                 clk_debug("pll id=%d set rate=%lu equal to parent rate\n",
292                                 pll->id, rate);
293                 cru_writel(PLL_MODE_SLOW(pll->id), CRU_MODE_CON);
294                 cru_writel((0x1 << (16+1)) | (0x1<<1), PLL_CONS(pll->id, 3));
295                 clk_debug("pll id=%d enter slow mode, set rate OK!\n", pll->id);
296                 return 0;
297         }
298
299         while(clk_set->rate) {
300                 if (clk_set->rate == rate) {
301                         break;
302                 }
303                 clk_set++;
304         }
305
306         if (clk_set->rate == rate) {
307                 ret = _pll_clk_set_rate(clk_set, pll->id, pll->lock);
308                 clk_debug("pll id=%d set rate=%lu OK!\n", pll->id, rate);
309         } else {
310                 clk_err("pll id=%d is no corresponding rate=%lu\n",
311                                 pll->id, rate);
312                 return -EINVAL;
313         }
314
315         return ret;
316 }
317
318 /* 1: use
319  * 0: no use
320  */
321 #define USE_ARM_GPLL    1
322
323 static int clk_apll_set_rate(struct clk_hw *hw, unsigned long rate,
324                 unsigned long parent_rate)
325 {
326         struct clk_pll *pll = to_clk_pll(hw);
327         struct clk *clk = hw->clk;
328         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
329         unsigned long arm_gpll_rate;
330         const struct apll_clk_set *ps;
331         u32 old_aclk_div = 0, new_aclk_div = 0;
332         u32 temp_div;
333         unsigned long flags;
334         int sel_gpll = 0;
335
336
337         if (rate == parent_rate) {
338                 clk_debug("pll id=%d set rate=%lu equal to parent rate\n",
339                                 pll->id, rate);
340                 cru_writel(PLL_MODE_SLOW(pll->id), CRU_MODE_CON);
341                 cru_writel((0x1 << (16+1)) | (0x1<<1), PLL_CONS(pll->id, 3));
342                 clk_debug("pll id=%d enter slow mode, set rate OK!\n", pll->id);
343                 return 0;
344         }
345
346 #if !USE_ARM_GPLL
347         goto CHANGE_APLL;
348 #endif
349
350         /* prepare arm_gpll before reparent clk_core to it */
351         if (!arm_gpll) {
352                 clk_err("clk arm_gpll is NULL!\n");
353                 goto CHANGE_APLL;
354         }
355
356         /* In rk3188, arm_gpll and cpu_gpll share a same gate,
357          * and aclk_cpu selects cpu_gpll as parent, thus this
358          * gate must keep enabled.
359          */
360 #if 0
361         if (clk_prepare(arm_gpll)) {
362                 clk_err("fail to prepare arm_gpll path\n");
363                 clk_unprepare(arm_gpll);
364                 goto CHANGE_APLL;
365         }
366
367         if (clk_enable(arm_gpll)) {
368                 clk_err("fail to enable arm_gpll path\n");
369                 clk_disable(arm_gpll);
370                 clk_unprepare(arm_gpll);
371                 goto CHANGE_APLL;
372         }
373 #endif
374
375         arm_gpll_rate = __clk_get_rate(arm_gpll);
376         temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
377         temp_div = (temp_div == 0) ? 1 : temp_div;
378         if (temp_div > CORE_CLK_MAX_DIV) {
379                 clk_debug("temp_div %d > max_div %d\n", temp_div,
380                                 CORE_CLK_MAX_DIV);
381                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
382                                 __clk_get_rate(clk), arm_gpll_rate);
383                 //clk_disable(arm_gpll);
384                 //clk_unprepare(arm_gpll);
385                 goto CHANGE_APLL;
386         }
387
388         local_irq_save(flags);
389
390         /* firstly set div, then select arm_gpll path */
391         cru_writel(CORE_CLK_DIV_W_MSK|CORE_CLK_DIV(temp_div), CRU_CLKSELS_CON(0));
392         cru_writel(CORE_SEL_PLL_W_MSK|CORE_SEL_GPLL, CRU_CLKSELS_CON(0));
393
394         sel_gpll = 1;
395         //loops_per_jiffy = lpj_gpll / temp_div;
396         smp_wmb();
397
398         local_irq_restore(flags);
399
400         clk_debug("temp select arm_gpll path, get rate %lu\n",
401                         arm_gpll_rate/temp_div);
402         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
403                         temp_div);
404
405 CHANGE_APLL:
406         ps = apll_get_best_set(rate, apll_table);
407         clk_debug("apll will set rate %lu\n", ps->rate);
408         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
409                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
410                         ps->clksel0, ps->clksel1);
411
412         local_irq_save(flags);
413
414         /* If core src don't select gpll, apll need to enter slow mode
415          * before power down
416          */
417         //FIXME
418         //if (!sel_gpll)
419         cru_writel(PLL_MODE_SLOW(pll->id), CRU_MODE_CON);
420
421         /* PLL power down */
422         cru_writel((0x1<<(16+1))|(0x1<<1), PLL_CONS(pll->id, 3));
423         dsb();
424         dsb();
425         dsb();
426         dsb();
427         dsb();
428         dsb();
429         cru_writel(ps->pllcon0, PLL_CONS(pll->id, 0));
430         cru_writel(ps->pllcon1, PLL_CONS(pll->id, 1));
431
432         rk30_clock_udelay(1);
433
434         /* PLL power up and wait for locked */
435         cru_writel((0x1<<(16+1)), PLL_CONS(pll->id, 3));
436         pll_wait_lock(pll->id);
437
438         old_aclk_div = GET_CORE_ACLK_VAL(cru_readl(CRU_CLKSELS_CON(1)) &
439                         CORE_ACLK_MSK);
440         new_aclk_div = GET_CORE_ACLK_VAL(ps->clksel1 & CORE_ACLK_MSK);
441
442         if (new_aclk_div >= old_aclk_div) {
443                 cru_writel(ps->clksel0, CRU_CLKSELS_CON(0));
444                 cru_writel(ps->clksel1, CRU_CLKSELS_CON(1));
445         }
446
447         /* PLL return from slow mode */
448         //FIXME
449         //if (!sel_gpll)
450         cru_writel(PLL_MODE_NORM(pll->id), CRU_MODE_CON);
451
452         /* reparent to apll, and set div to 1 */
453         if (sel_gpll) {
454                 cru_writel(CORE_SEL_PLL_W_MSK|CORE_SEL_APLL, CRU_CLKSELS_CON(0));
455                 cru_writel(CORE_CLK_DIV_W_MSK|CORE_CLK_DIV(1), CRU_CLKSELS_CON(0));
456         }
457
458         if (old_aclk_div > new_aclk_div) {
459                 cru_writel(ps->clksel0, CRU_CLKSELS_CON(0));
460                 cru_writel(ps->clksel1, CRU_CLKSELS_CON(1));
461         }
462
463         //loops_per_jiffy = ps->lpj;
464         smp_wmb();
465
466         local_irq_restore(flags);
467
468         if (sel_gpll) {
469                 sel_gpll = 0;
470                 //clk_disable(arm_gpll);
471                 //clk_unprepare(arm_gpll);
472         }
473
474         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
475
476         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
477                         ps->rate,
478                         cru_readl(PLL_CONS(pll->id, 0)),cru_readl(PLL_CONS(pll->id, 1)),
479                         cru_readl(PLL_CONS(pll->id, 2)),cru_readl(PLL_CONS(pll->id, 3)),
480                         cru_readl(CRU_CLKSELS_CON(0)),cru_readl(CRU_CLKSELS_CON(1)));
481
482         return 0;
483 }
484
485 static int clk_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
486                 unsigned long parent_rate)
487 {
488         return 0;
489 }
490
491 static int clk_gpll_set_rate(struct clk_hw *hw, unsigned long rate,
492                 unsigned long parent_rate)
493 {
494         int ret = clk_pll_com_set_rate(hw, rate, parent_rate);
495
496         //if(!ret)
497         //      lpj_gpll = CLK_LOOPS_RECALC(clk_pll_recalc_rate(hw, parent_rate));
498
499         return ret;
500 }
501
502 static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
503                 unsigned long parent_rate)
504 {
505         struct clk_pll *pll = to_clk_pll(hw);
506         int ret = 0;
507
508         switch (pll->id){
509                 case APLL_ID: {
510                                       ret = clk_apll_set_rate(hw, rate, parent_rate);
511                                       break;
512                               }
513                 case DPLL_ID: {
514                                       ret = clk_dpll_set_rate(hw, rate, parent_rate);
515                                       break;
516                               }
517                 case GPLL_ID: {
518                                       ret = clk_gpll_set_rate(hw, rate, parent_rate);
519                                       break;
520                               }
521                 default: {
522                                  ret = clk_pll_com_set_rate(hw, rate, parent_rate);
523                                  break;
524                          }
525         }
526
527         return ret;
528 }
529
530 const struct clk_ops clk_pll_ops = {
531         .recalc_rate = clk_pll_recalc_rate,
532         .round_rate = clk_pll_round_rate,
533         .set_rate = clk_pll_set_rate,
534 };
535
536 EXPORT_SYMBOL_GPL(clk_pll_ops);
537
538
539 struct clk *rk_clk_register_pll(struct device *dev, const char *name,
540                 const char *parent_name, unsigned long flags, void __iomem *reg,
541                 u32 width, u8 id, spinlock_t *lock)
542 {
543         struct clk_pll *pll;
544         struct clk *clk;
545         struct clk_init_data init;
546
547
548         clk_debug("%s: pll name = %s, id = %d, register start!\n",__func__,name,id);
549
550 #if 0
551         if(id >= END_PLL_ID){
552                 clk_err("%s: PLL id = %d >= END_PLL_ID = %d\n", __func__,
553                                 id, END_PLL_ID);
554                 return ERR_PTR(-EINVAL);
555         }
556 #endif
557
558         /* allocate the pll */
559         pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
560         if (!pll) {
561                 clk_err("%s: could not allocate pll clk\n", __func__);
562                 return ERR_PTR(-ENOMEM);
563         }
564
565         init.name = name;
566         init.flags = flags;
567         init.parent_names = (parent_name ? &parent_name: NULL);
568         init.num_parents = (parent_name ? 1 : 0);
569         init.ops = &clk_pll_ops;
570
571         /* struct clk_pll assignments */
572         pll->reg = reg;
573         pll->width = width;
574         pll->id = id;
575         pll->lock = lock;
576         pll->hw.init = &init;
577
578         /* register the clock */
579         clk = clk_register(dev, &pll->hw);
580
581         if (IS_ERR(clk))
582                 kfree(pll);
583
584         clk_debug("%s: pll name = %s, id = %d, register finish!\n",__func__,name,id);
585
586         return clk;
587 }
588