]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/armv7/exynos/clock.c
Exynos: clock: change mask bits as per peripheral
[u-boot] / arch / arm / cpu / armv7 / exynos / clock.c
1 /*
2  * Copyright (C) 2010 Samsung Electronics
3  * Minkyu Kang <mk7.kang@samsung.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <asm/io.h>
10 #include <asm/arch/clock.h>
11 #include <asm/arch/clk.h>
12 #include <asm/arch/periph.h>
13
14 #define PLL_DIV_1024    1024
15 #define PLL_DIV_65535   65535
16 #define PLL_DIV_65536   65536
17
18 /* *
19  * This structure is to store the src bit, div bit and prediv bit
20  * positions of the peripheral clocks of the src and div registers
21  */
22 struct clk_bit_info {
23         enum periph_id id;
24         int32_t src_mask;
25         int32_t div_mask;
26         int32_t prediv_mask;
27         int8_t src_bit;
28         int8_t div_bit;
29         int8_t prediv_bit;
30 };
31
32 static struct clk_bit_info exynos5_bit_info[] = {
33         /* periph id            s_mask  d_mask  p_mask  s_bit   d_bit   p_bit */
34         {PERIPH_ID_UART0,       0xf,    0xf,    -1,     0,      0,      -1},
35         {PERIPH_ID_UART1,       0xf,    0xf,    -1,     4,      4,      -1},
36         {PERIPH_ID_UART2,       0xf,    0xf,    -1,     8,      8,      -1},
37         {PERIPH_ID_UART3,       0xf,    0xf,    -1,     12,     12,     -1},
38         {PERIPH_ID_I2C0,        -1,     0x7,    0x7,    -1,     24,     0},
39         {PERIPH_ID_I2C1,        -1,     0x7,    0x7,    -1,     24,     0},
40         {PERIPH_ID_I2C2,        -1,     0x7,    0x7,    -1,     24,     0},
41         {PERIPH_ID_I2C3,        -1,     0x7,    0x7,    -1,     24,     0},
42         {PERIPH_ID_I2C4,        -1,     0x7,    0x7,    -1,     24,     0},
43         {PERIPH_ID_I2C5,        -1,     0x7,    0x7,    -1,     24,     0},
44         {PERIPH_ID_I2C6,        -1,     0x7,    0x7,    -1,     24,     0},
45         {PERIPH_ID_I2C7,        -1,     0x7,    0x7,    -1,     24,     0},
46         {PERIPH_ID_SPI0,        0xf,    0xf,    0xff,   16,     0,      8},
47         {PERIPH_ID_SPI1,        0xf,    0xf,    0xff,   20,     16,     24},
48         {PERIPH_ID_SPI2,        0xf,    0xf,    0xff,   24,     0,      8},
49         {PERIPH_ID_SDMMC0,      0xf,    0xf,    0xff,   0,      0,      8},
50         {PERIPH_ID_SDMMC1,      0xf,    0xf,    0xff,   4,      16,     24},
51         {PERIPH_ID_SDMMC2,      0xf,    0xf,    0xff,   8,      0,      8},
52         {PERIPH_ID_SDMMC3,      0xf,    0xf,    0xff,   12,     16,     24},
53         {PERIPH_ID_I2S0,        0xf,    0xf,    0xff,   0,      0,      4},
54         {PERIPH_ID_I2S1,        0xf,    0xf,    0xff,   4,      12,     16},
55         {PERIPH_ID_SPI3,        0xf,    0xf,    0xff,   0,      0,      4},
56         {PERIPH_ID_SPI4,        0xf,    0xf,    0xff,   4,      12,     16},
57         {PERIPH_ID_SDMMC4,      0xf,    0xf,    0xff,   16,     0,      8},
58         {PERIPH_ID_PWM0,        0xf,    0xf,    -1,     24,     0,      -1},
59         {PERIPH_ID_PWM1,        0xf,    0xf,    -1,     24,     0,      -1},
60         {PERIPH_ID_PWM2,        0xf,    0xf,    -1,     24,     0,      -1},
61         {PERIPH_ID_PWM3,        0xf,    0xf,    -1,     24,     0,      -1},
62         {PERIPH_ID_PWM4,        0xf,    0xf,    -1,     24,     0,      -1},
63
64         {PERIPH_ID_NONE,        -1,     -1,     -1,     -1,     -1,     -1},
65 };
66
67 static struct clk_bit_info exynos542x_bit_info[] = {
68         /* periph id            s_mask  d_mask  p_mask  s_bit   d_bit   p_bit */
69         {PERIPH_ID_UART0,       0xf,    0xf,    -1,     4,      8,      -1},
70         {PERIPH_ID_UART1,       0xf,    0xf,    -1,     8,      12,     -1},
71         {PERIPH_ID_UART2,       0xf,    0xf,    -1,     12,     16,     -1},
72         {PERIPH_ID_UART3,       0xf,    0xf,    -1,     16,     20,     -1},
73         {PERIPH_ID_I2C0,        -1,     0x3f,   -1,     -1,     8,      -1},
74         {PERIPH_ID_I2C1,        -1,     0x3f,   -1,     -1,     8,      -1},
75         {PERIPH_ID_I2C2,        -1,     0x3f,   -1,     -1,     8,      -1},
76         {PERIPH_ID_I2C3,        -1,     0x3f,   -1,     -1,     8,      -1},
77         {PERIPH_ID_I2C4,        -1,     0x3f,   -1,     -1,     8,      -1},
78         {PERIPH_ID_I2C5,        -1,     0x3f,   -1,     -1,     8,      -1},
79         {PERIPH_ID_I2C6,        -1,     0x3f,   -1,     -1,     8,      -1},
80         {PERIPH_ID_I2C7,        -1,     0x3f,   -1,     -1,     8,      -1},
81         {PERIPH_ID_SPI0,        0xf,    0xf,    0xff,   20,     20,     8},
82         {PERIPH_ID_SPI1,        0xf,    0xf,    0xff,   24,     24,     16},
83         {PERIPH_ID_SPI2,        0xf,    0xf,    0xff,   28,     28,     24},
84         {PERIPH_ID_SDMMC0,      0x7,    0x3ff,  -1,     8,      0,      -1},
85         {PERIPH_ID_SDMMC1,      0x7,    0x3ff,  -1,     12,     10,     -1},
86         {PERIPH_ID_SDMMC2,      0x7,    0x3ff,  -1,     16,     20,     -1},
87         {PERIPH_ID_I2C8,        -1,     0x3f,   -1,     -1,     8,      -1},
88         {PERIPH_ID_I2C9,        -1,     0x3f,   -1,     -1,     8,      -1},
89         {PERIPH_ID_I2S0,        0xf,    0xf,    0xff,   0,      0,      4},
90         {PERIPH_ID_I2S1,        0xf,    0xf,    0xff,   4,      12,     16},
91         {PERIPH_ID_SPI3,        0xf,    0xf,    0xff,   12,     16,     0},
92         {PERIPH_ID_SPI4,        0xf,    0xf,    0xff,   16,     20,     8},
93         {PERIPH_ID_PWM0,        0xf,    0xf,    -1,     24,     28,     -1},
94         {PERIPH_ID_PWM1,        0xf,    0xf,    -1,     24,     28,     -1},
95         {PERIPH_ID_PWM2,        0xf,    0xf,    -1,     24,     28,     -1},
96         {PERIPH_ID_PWM3,        0xf,    0xf,    -1,     24,     28,     -1},
97         {PERIPH_ID_PWM4,        0xf,    0xf,    -1,     24,     28,     -1},
98         {PERIPH_ID_I2C10,       -1,     0x3f,   -1,     -1,     8,      -1},
99
100         {PERIPH_ID_NONE,        -1,     -1,     -1,     -1,     -1,     -1},
101 };
102
103 /* Epll Clock division values to achive different frequency output */
104 static struct set_epll_con_val exynos5_epll_div[] = {
105         { 192000000, 0, 48, 3, 1, 0 },
106         { 180000000, 0, 45, 3, 1, 0 },
107         {  73728000, 1, 73, 3, 3, 47710 },
108         {  67737600, 1, 90, 4, 3, 20762 },
109         {  49152000, 0, 49, 3, 3, 9961 },
110         {  45158400, 0, 45, 3, 3, 10381 },
111         { 180633600, 0, 45, 3, 1, 10381 }
112 };
113
114 /* exynos: return pll clock frequency */
115 static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
116 {
117         unsigned long m, p, s = 0, mask, fout;
118         unsigned int div;
119         unsigned int freq;
120         /*
121          * APLL_CON: MIDV [25:16]
122          * MPLL_CON: MIDV [25:16]
123          * EPLL_CON: MIDV [24:16]
124          * VPLL_CON: MIDV [24:16]
125          * BPLL_CON: MIDV [25:16]: Exynos5
126          */
127         if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL ||
128             pllreg == SPLL)
129                 mask = 0x3ff;
130         else
131                 mask = 0x1ff;
132
133         m = (r >> 16) & mask;
134
135         /* PDIV [13:8] */
136         p = (r >> 8) & 0x3f;
137         /* SDIV [2:0] */
138         s = r & 0x7;
139
140         freq = CONFIG_SYS_CLK_FREQ;
141
142         if (pllreg == EPLL || pllreg == RPLL) {
143                 k = k & 0xffff;
144                 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
145                 fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
146         } else if (pllreg == VPLL) {
147                 k = k & 0xfff;
148
149                 /*
150                  * Exynos4210
151                  * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
152                  *
153                  * Exynos4412
154                  * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
155                  *
156                  * Exynos5250
157                  * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
158                  */
159                 if (proid_is_exynos4210())
160                         div = PLL_DIV_1024;
161                 else if (proid_is_exynos4412())
162                         div = PLL_DIV_65535;
163                 else if (proid_is_exynos5250() || proid_is_exynos5420()
164                          || proid_is_exynos5800())
165                         div = PLL_DIV_65536;
166                 else
167                         return 0;
168
169                 fout = (m + k / div) * (freq / (p * (1 << s)));
170         } else {
171                 /*
172                  * Exynos4412 / Exynos5250
173                  * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
174                  *
175                  * Exynos4210
176                  * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
177                  */
178                 if (proid_is_exynos4210())
179                         fout = m * (freq / (p * (1 << (s - 1))));
180                 else
181                         fout = m * (freq / (p * (1 << s)));
182         }
183         return fout;
184 }
185
186 /* exynos4: return pll clock frequency */
187 static unsigned long exynos4_get_pll_clk(int pllreg)
188 {
189         struct exynos4_clock *clk =
190                 (struct exynos4_clock *)samsung_get_base_clock();
191         unsigned long r, k = 0;
192
193         switch (pllreg) {
194         case APLL:
195                 r = readl(&clk->apll_con0);
196                 break;
197         case MPLL:
198                 r = readl(&clk->mpll_con0);
199                 break;
200         case EPLL:
201                 r = readl(&clk->epll_con0);
202                 k = readl(&clk->epll_con1);
203                 break;
204         case VPLL:
205                 r = readl(&clk->vpll_con0);
206                 k = readl(&clk->vpll_con1);
207                 break;
208         default:
209                 printf("Unsupported PLL (%d)\n", pllreg);
210                 return 0;
211         }
212
213         return exynos_get_pll_clk(pllreg, r, k);
214 }
215
216 /* exynos4x12: return pll clock frequency */
217 static unsigned long exynos4x12_get_pll_clk(int pllreg)
218 {
219         struct exynos4x12_clock *clk =
220                 (struct exynos4x12_clock *)samsung_get_base_clock();
221         unsigned long r, k = 0;
222
223         switch (pllreg) {
224         case APLL:
225                 r = readl(&clk->apll_con0);
226                 break;
227         case MPLL:
228                 r = readl(&clk->mpll_con0);
229                 break;
230         case EPLL:
231                 r = readl(&clk->epll_con0);
232                 k = readl(&clk->epll_con1);
233                 break;
234         case VPLL:
235                 r = readl(&clk->vpll_con0);
236                 k = readl(&clk->vpll_con1);
237                 break;
238         default:
239                 printf("Unsupported PLL (%d)\n", pllreg);
240                 return 0;
241         }
242
243         return exynos_get_pll_clk(pllreg, r, k);
244 }
245
246 /* exynos5: return pll clock frequency */
247 static unsigned long exynos5_get_pll_clk(int pllreg)
248 {
249         struct exynos5_clock *clk =
250                 (struct exynos5_clock *)samsung_get_base_clock();
251         unsigned long r, k = 0, fout;
252         unsigned int pll_div2_sel, fout_sel;
253
254         switch (pllreg) {
255         case APLL:
256                 r = readl(&clk->apll_con0);
257                 break;
258         case MPLL:
259                 r = readl(&clk->mpll_con0);
260                 break;
261         case EPLL:
262                 r = readl(&clk->epll_con0);
263                 k = readl(&clk->epll_con1);
264                 break;
265         case VPLL:
266                 r = readl(&clk->vpll_con0);
267                 k = readl(&clk->vpll_con1);
268                 break;
269         case BPLL:
270                 r = readl(&clk->bpll_con0);
271                 break;
272         default:
273                 printf("Unsupported PLL (%d)\n", pllreg);
274                 return 0;
275         }
276
277         fout = exynos_get_pll_clk(pllreg, r, k);
278
279         /* According to the user manual, in EVT1 MPLL and BPLL always gives
280          * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
281         if (pllreg == MPLL || pllreg == BPLL) {
282                 pll_div2_sel = readl(&clk->pll_div2_sel);
283
284                 switch (pllreg) {
285                 case MPLL:
286                         fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
287                                         & MPLL_FOUT_SEL_MASK;
288                         break;
289                 case BPLL:
290                         fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
291                                         & BPLL_FOUT_SEL_MASK;
292                         break;
293                 default:
294                         fout_sel = -1;
295                         break;
296                 }
297
298                 if (fout_sel == 0)
299                         fout /= 2;
300         }
301
302         return fout;
303 }
304
305 /* exynos542x: return pll clock frequency */
306 static unsigned long exynos542x_get_pll_clk(int pllreg)
307 {
308         struct exynos5420_clock *clk =
309                 (struct exynos5420_clock *)samsung_get_base_clock();
310         unsigned long r, k = 0;
311
312         switch (pllreg) {
313         case APLL:
314                 r = readl(&clk->apll_con0);
315                 break;
316         case MPLL:
317                 r = readl(&clk->mpll_con0);
318                 break;
319         case EPLL:
320                 r = readl(&clk->epll_con0);
321                 k = readl(&clk->epll_con1);
322                 break;
323         case VPLL:
324                 r = readl(&clk->vpll_con0);
325                 k = readl(&clk->vpll_con1);
326                 break;
327         case BPLL:
328                 r = readl(&clk->bpll_con0);
329                 break;
330         case RPLL:
331                 r = readl(&clk->rpll_con0);
332                 k = readl(&clk->rpll_con1);
333                 break;
334         case SPLL:
335                 r = readl(&clk->spll_con0);
336                 break;
337         default:
338                 printf("Unsupported PLL (%d)\n", pllreg);
339                 return 0;
340         }
341
342         return exynos_get_pll_clk(pllreg, r, k);
343 }
344
345 static struct clk_bit_info *get_clk_bit_info(int peripheral)
346 {
347         int i;
348         struct clk_bit_info *info;
349
350         if (proid_is_exynos5420() || proid_is_exynos5800())
351                 info = exynos542x_bit_info;
352         else
353                 info = exynos5_bit_info;
354
355         for (i = 0; info[i].id != PERIPH_ID_NONE; i++) {
356                 if (info[i].id == peripheral)
357                         break;
358         }
359
360         if (info[i].id == PERIPH_ID_NONE)
361                 debug("ERROR: Peripheral ID %d not found\n", peripheral);
362
363         return &info[i];
364 }
365
366 static unsigned long exynos5_get_periph_rate(int peripheral)
367 {
368         struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
369         unsigned long sclk, sub_clk = 0;
370         unsigned int src, div, sub_div = 0;
371         struct exynos5_clock *clk =
372                         (struct exynos5_clock *)samsung_get_base_clock();
373
374         switch (peripheral) {
375         case PERIPH_ID_UART0:
376         case PERIPH_ID_UART1:
377         case PERIPH_ID_UART2:
378         case PERIPH_ID_UART3:
379                 src = readl(&clk->src_peric0);
380                 div = readl(&clk->div_peric0);
381                 break;
382         case PERIPH_ID_PWM0:
383         case PERIPH_ID_PWM1:
384         case PERIPH_ID_PWM2:
385         case PERIPH_ID_PWM3:
386         case PERIPH_ID_PWM4:
387                 src = readl(&clk->src_peric0);
388                 div = readl(&clk->div_peric3);
389                 break;
390         case PERIPH_ID_I2S0:
391                 src = readl(&clk->src_mau);
392                 div = readl(&clk->div_mau);
393         case PERIPH_ID_SPI0:
394         case PERIPH_ID_SPI1:
395                 src = readl(&clk->src_peric1);
396                 div = readl(&clk->div_peric1);
397                 break;
398         case PERIPH_ID_SPI2:
399                 src = readl(&clk->src_peric1);
400                 div = readl(&clk->div_peric2);
401                 break;
402         case PERIPH_ID_SPI3:
403         case PERIPH_ID_SPI4:
404                 src = readl(&clk->sclk_src_isp);
405                 div = readl(&clk->sclk_div_isp);
406                 break;
407         case PERIPH_ID_SDMMC0:
408         case PERIPH_ID_SDMMC1:
409                 src = readl(&clk->src_fsys);
410                 div = readl(&clk->div_fsys1);
411                 break;
412         case PERIPH_ID_SDMMC2:
413         case PERIPH_ID_SDMMC3:
414                 src = readl(&clk->src_fsys);
415                 div = readl(&clk->div_fsys2);
416                 break;
417         case PERIPH_ID_I2C0:
418         case PERIPH_ID_I2C1:
419         case PERIPH_ID_I2C2:
420         case PERIPH_ID_I2C3:
421         case PERIPH_ID_I2C4:
422         case PERIPH_ID_I2C5:
423         case PERIPH_ID_I2C6:
424         case PERIPH_ID_I2C7:
425                 sclk = exynos5_get_pll_clk(MPLL);
426                 sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit)
427                             & bit_info->div_mask) + 1;
428                 div = ((readl(&clk->div_top0) >> bit_info->prediv_bit)
429                         & bit_info->prediv_mask) + 1;
430                 return (sclk / sub_div) / div;
431         default:
432                 debug("%s: invalid peripheral %d", __func__, peripheral);
433                 return -1;
434         };
435
436         if (bit_info->src_bit >= 0)
437                 src = (src >> bit_info->src_bit) & bit_info->src_mask;
438
439         switch (src) {
440         case EXYNOS_SRC_MPLL:
441                 sclk = exynos5_get_pll_clk(MPLL);
442                 break;
443         case EXYNOS_SRC_EPLL:
444                 sclk = exynos5_get_pll_clk(EPLL);
445                 break;
446         case EXYNOS_SRC_VPLL:
447                 sclk = exynos5_get_pll_clk(VPLL);
448                 break;
449         default:
450                 return 0;
451         }
452
453         /* Ratio clock division for this peripheral */
454         if (bit_info->div_bit >= 0) {
455                 sub_div = (div >> bit_info->div_bit) & bit_info->div_mask;
456                 sub_clk = sclk / (sub_div + 1);
457         }
458
459         if (bit_info->prediv_bit >= 0) {
460                 div = (div >> bit_info->prediv_bit) & bit_info->prediv_mask;
461                 return sub_clk / (div + 1);
462         }
463
464         return sub_clk;
465 }
466
467 static unsigned long exynos542x_get_periph_rate(int peripheral)
468 {
469         struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
470         unsigned long sclk, sub_clk = 0;
471         unsigned int src, div, sub_div = 0;
472         struct exynos5420_clock *clk =
473                         (struct exynos5420_clock *)samsung_get_base_clock();
474
475         switch (peripheral) {
476         case PERIPH_ID_UART0:
477         case PERIPH_ID_UART1:
478         case PERIPH_ID_UART2:
479         case PERIPH_ID_UART3:
480         case PERIPH_ID_PWM0:
481         case PERIPH_ID_PWM1:
482         case PERIPH_ID_PWM2:
483         case PERIPH_ID_PWM3:
484         case PERIPH_ID_PWM4:
485                 src = readl(&clk->src_peric0);
486                 div = readl(&clk->div_peric0);
487                 break;
488         case PERIPH_ID_SPI0:
489         case PERIPH_ID_SPI1:
490         case PERIPH_ID_SPI2:
491                 src = readl(&clk->src_peric1);
492                 div = readl(&clk->div_peric1);
493                 sub_div = readl(&clk->div_peric4);
494                 break;
495         case PERIPH_ID_SPI3:
496         case PERIPH_ID_SPI4:
497                 src = readl(&clk->src_isp);
498                 div = readl(&clk->div_isp1);
499                 sub_div = readl(&clk->div_isp1);
500                 break;
501         case PERIPH_ID_SDMMC0:
502         case PERIPH_ID_SDMMC1:
503         case PERIPH_ID_SDMMC2:
504         case PERIPH_ID_SDMMC3:
505                 src = readl(&clk->src_fsys);
506                 div = readl(&clk->div_fsys1);
507                 break;
508         case PERIPH_ID_I2C0:
509         case PERIPH_ID_I2C1:
510         case PERIPH_ID_I2C2:
511         case PERIPH_ID_I2C3:
512         case PERIPH_ID_I2C4:
513         case PERIPH_ID_I2C5:
514         case PERIPH_ID_I2C6:
515         case PERIPH_ID_I2C7:
516         case PERIPH_ID_I2C8:
517         case PERIPH_ID_I2C9:
518         case PERIPH_ID_I2C10:
519                 sclk = exynos542x_get_pll_clk(MPLL);
520                 sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit)
521                             & bit_info->div_mask) + 1;
522                 return sclk / sub_div;
523         default:
524                 debug("%s: invalid peripheral %d", __func__, peripheral);
525                 return -1;
526         };
527
528         if (bit_info->src_bit >= 0)
529                 src = (src >> bit_info->src_bit) & bit_info->src_mask;
530
531         switch (src) {
532         case EXYNOS542X_SRC_MPLL:
533                 sclk = exynos542x_get_pll_clk(MPLL);
534                 break;
535         case EXYNOS542X_SRC_SPLL:
536                 sclk = exynos542x_get_pll_clk(SPLL);
537                 break;
538         case EXYNOS542X_SRC_EPLL:
539                 sclk = exynos542x_get_pll_clk(EPLL);
540                 break;
541         case EXYNOS542X_SRC_RPLL:
542                 sclk = exynos542x_get_pll_clk(RPLL);
543                 break;
544         default:
545                 return 0;
546         }
547
548         /* Ratio clock division for this peripheral */
549         if (bit_info->div_bit >= 0) {
550                 div = (div >> bit_info->div_bit) & bit_info->div_mask;
551                 sub_clk = sclk / (div + 1);
552         }
553
554         if (bit_info->prediv_bit >= 0) {
555                 sub_div = (sub_div >> bit_info->prediv_bit)
556                                                 & bit_info->prediv_mask;
557                 return sub_clk / (sub_div + 1);
558         }
559
560         return sub_clk;
561 }
562
563 unsigned long clock_get_periph_rate(int peripheral)
564 {
565         if (cpu_is_exynos5()) {
566                 if (proid_is_exynos5420() || proid_is_exynos5800())
567                         return exynos542x_get_periph_rate(peripheral);
568                 return exynos5_get_periph_rate(peripheral);
569         } else {
570                 return 0;
571         }
572 }
573
574 /* exynos4: return ARM clock frequency */
575 static unsigned long exynos4_get_arm_clk(void)
576 {
577         struct exynos4_clock *clk =
578                 (struct exynos4_clock *)samsung_get_base_clock();
579         unsigned long div;
580         unsigned long armclk;
581         unsigned int core_ratio;
582         unsigned int core2_ratio;
583
584         div = readl(&clk->div_cpu0);
585
586         /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
587         core_ratio = (div >> 0) & 0x7;
588         core2_ratio = (div >> 28) & 0x7;
589
590         armclk = get_pll_clk(APLL) / (core_ratio + 1);
591         armclk /= (core2_ratio + 1);
592
593         return armclk;
594 }
595
596 /* exynos4x12: return ARM clock frequency */
597 static unsigned long exynos4x12_get_arm_clk(void)
598 {
599         struct exynos4x12_clock *clk =
600                 (struct exynos4x12_clock *)samsung_get_base_clock();
601         unsigned long div;
602         unsigned long armclk;
603         unsigned int core_ratio;
604         unsigned int core2_ratio;
605
606         div = readl(&clk->div_cpu0);
607
608         /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
609         core_ratio = (div >> 0) & 0x7;
610         core2_ratio = (div >> 28) & 0x7;
611
612         armclk = get_pll_clk(APLL) / (core_ratio + 1);
613         armclk /= (core2_ratio + 1);
614
615         return armclk;
616 }
617
618 /* exynos5: return ARM clock frequency */
619 static unsigned long exynos5_get_arm_clk(void)
620 {
621         struct exynos5_clock *clk =
622                 (struct exynos5_clock *)samsung_get_base_clock();
623         unsigned long div;
624         unsigned long armclk;
625         unsigned int arm_ratio;
626         unsigned int arm2_ratio;
627
628         div = readl(&clk->div_cpu0);
629
630         /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
631         arm_ratio = (div >> 0) & 0x7;
632         arm2_ratio = (div >> 28) & 0x7;
633
634         armclk = get_pll_clk(APLL) / (arm_ratio + 1);
635         armclk /= (arm2_ratio + 1);
636
637         return armclk;
638 }
639
640 /* exynos4: return pwm clock frequency */
641 static unsigned long exynos4_get_pwm_clk(void)
642 {
643         struct exynos4_clock *clk =
644                 (struct exynos4_clock *)samsung_get_base_clock();
645         unsigned long pclk, sclk;
646         unsigned int sel;
647         unsigned int ratio;
648
649         if (s5p_get_cpu_rev() == 0) {
650                 /*
651                  * CLK_SRC_PERIL0
652                  * PWM_SEL [27:24]
653                  */
654                 sel = readl(&clk->src_peril0);
655                 sel = (sel >> 24) & 0xf;
656
657                 if (sel == 0x6)
658                         sclk = get_pll_clk(MPLL);
659                 else if (sel == 0x7)
660                         sclk = get_pll_clk(EPLL);
661                 else if (sel == 0x8)
662                         sclk = get_pll_clk(VPLL);
663                 else
664                         return 0;
665
666                 /*
667                  * CLK_DIV_PERIL3
668                  * PWM_RATIO [3:0]
669                  */
670                 ratio = readl(&clk->div_peril3);
671                 ratio = ratio & 0xf;
672         } else if (s5p_get_cpu_rev() == 1) {
673                 sclk = get_pll_clk(MPLL);
674                 ratio = 8;
675         } else
676                 return 0;
677
678         pclk = sclk / (ratio + 1);
679
680         return pclk;
681 }
682
683 /* exynos4x12: return pwm clock frequency */
684 static unsigned long exynos4x12_get_pwm_clk(void)
685 {
686         unsigned long pclk, sclk;
687         unsigned int ratio;
688
689         sclk = get_pll_clk(MPLL);
690         ratio = 8;
691
692         pclk = sclk / (ratio + 1);
693
694         return pclk;
695 }
696
697 /* exynos4: return uart clock frequency */
698 static unsigned long exynos4_get_uart_clk(int dev_index)
699 {
700         struct exynos4_clock *clk =
701                 (struct exynos4_clock *)samsung_get_base_clock();
702         unsigned long uclk, sclk;
703         unsigned int sel;
704         unsigned int ratio;
705
706         /*
707          * CLK_SRC_PERIL0
708          * UART0_SEL [3:0]
709          * UART1_SEL [7:4]
710          * UART2_SEL [8:11]
711          * UART3_SEL [12:15]
712          * UART4_SEL [16:19]
713          * UART5_SEL [23:20]
714          */
715         sel = readl(&clk->src_peril0);
716         sel = (sel >> (dev_index << 2)) & 0xf;
717
718         if (sel == 0x6)
719                 sclk = get_pll_clk(MPLL);
720         else if (sel == 0x7)
721                 sclk = get_pll_clk(EPLL);
722         else if (sel == 0x8)
723                 sclk = get_pll_clk(VPLL);
724         else
725                 return 0;
726
727         /*
728          * CLK_DIV_PERIL0
729          * UART0_RATIO [3:0]
730          * UART1_RATIO [7:4]
731          * UART2_RATIO [8:11]
732          * UART3_RATIO [12:15]
733          * UART4_RATIO [16:19]
734          * UART5_RATIO [23:20]
735          */
736         ratio = readl(&clk->div_peril0);
737         ratio = (ratio >> (dev_index << 2)) & 0xf;
738
739         uclk = sclk / (ratio + 1);
740
741         return uclk;
742 }
743
744 /* exynos4x12: return uart clock frequency */
745 static unsigned long exynos4x12_get_uart_clk(int dev_index)
746 {
747         struct exynos4x12_clock *clk =
748                 (struct exynos4x12_clock *)samsung_get_base_clock();
749         unsigned long uclk, sclk;
750         unsigned int sel;
751         unsigned int ratio;
752
753         /*
754          * CLK_SRC_PERIL0
755          * UART0_SEL [3:0]
756          * UART1_SEL [7:4]
757          * UART2_SEL [8:11]
758          * UART3_SEL [12:15]
759          * UART4_SEL [16:19]
760          */
761         sel = readl(&clk->src_peril0);
762         sel = (sel >> (dev_index << 2)) & 0xf;
763
764         if (sel == 0x6)
765                 sclk = get_pll_clk(MPLL);
766         else if (sel == 0x7)
767                 sclk = get_pll_clk(EPLL);
768         else if (sel == 0x8)
769                 sclk = get_pll_clk(VPLL);
770         else
771                 return 0;
772
773         /*
774          * CLK_DIV_PERIL0
775          * UART0_RATIO [3:0]
776          * UART1_RATIO [7:4]
777          * UART2_RATIO [8:11]
778          * UART3_RATIO [12:15]
779          * UART4_RATIO [16:19]
780          */
781         ratio = readl(&clk->div_peril0);
782         ratio = (ratio >> (dev_index << 2)) & 0xf;
783
784         uclk = sclk / (ratio + 1);
785
786         return uclk;
787 }
788
789 static unsigned long exynos4_get_mmc_clk(int dev_index)
790 {
791         struct exynos4_clock *clk =
792                 (struct exynos4_clock *)samsung_get_base_clock();
793         unsigned long uclk, sclk;
794         unsigned int sel, ratio, pre_ratio;
795         int shift = 0;
796
797         sel = readl(&clk->src_fsys);
798         sel = (sel >> (dev_index << 2)) & 0xf;
799
800         if (sel == 0x6)
801                 sclk = get_pll_clk(MPLL);
802         else if (sel == 0x7)
803                 sclk = get_pll_clk(EPLL);
804         else if (sel == 0x8)
805                 sclk = get_pll_clk(VPLL);
806         else
807                 return 0;
808
809         switch (dev_index) {
810         case 0:
811         case 1:
812                 ratio = readl(&clk->div_fsys1);
813                 pre_ratio = readl(&clk->div_fsys1);
814                 break;
815         case 2:
816         case 3:
817                 ratio = readl(&clk->div_fsys2);
818                 pre_ratio = readl(&clk->div_fsys2);
819                 break;
820         case 4:
821                 ratio = readl(&clk->div_fsys3);
822                 pre_ratio = readl(&clk->div_fsys3);
823                 break;
824         default:
825                 return 0;
826         }
827
828         if (dev_index == 1 || dev_index == 3)
829                 shift = 16;
830
831         ratio = (ratio >> shift) & 0xf;
832         pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
833         uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
834
835         return uclk;
836 }
837
838 /* exynos4: set the mmc clock */
839 static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
840 {
841         struct exynos4_clock *clk =
842                 (struct exynos4_clock *)samsung_get_base_clock();
843         unsigned int addr, clear_bit, set_bit;
844
845         /*
846          * CLK_DIV_FSYS1
847          * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
848          * CLK_DIV_FSYS2
849          * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
850          * CLK_DIV_FSYS3
851          * MMC4_RATIO [3:0]
852          */
853         if (dev_index < 2) {
854                 addr = (unsigned int)&clk->div_fsys1;
855                 clear_bit = MASK_PRE_RATIO(dev_index);
856                 set_bit = SET_PRE_RATIO(dev_index, div);
857         } else if (dev_index == 4) {
858                 addr = (unsigned int)&clk->div_fsys3;
859                 dev_index -= 4;
860                 /* MMC4 is controlled with the MMC4_RATIO value */
861                 clear_bit = MASK_RATIO(dev_index);
862                 set_bit = SET_RATIO(dev_index, div);
863         } else {
864                 addr = (unsigned int)&clk->div_fsys2;
865                 dev_index -= 2;
866                 clear_bit = MASK_PRE_RATIO(dev_index);
867                 set_bit = SET_PRE_RATIO(dev_index, div);
868         }
869
870         clrsetbits_le32(addr, clear_bit, set_bit);
871 }
872
873 /* exynos5: set the mmc clock */
874 static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
875 {
876         struct exynos5_clock *clk =
877                 (struct exynos5_clock *)samsung_get_base_clock();
878         unsigned int addr;
879
880         /*
881          * CLK_DIV_FSYS1
882          * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
883          * CLK_DIV_FSYS2
884          * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
885          */
886         if (dev_index < 2) {
887                 addr = (unsigned int)&clk->div_fsys1;
888         } else {
889                 addr = (unsigned int)&clk->div_fsys2;
890                 dev_index -= 2;
891         }
892
893         clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
894                         (div & 0xff) << ((dev_index << 4) + 8));
895 }
896
897 /* exynos5: set the mmc clock */
898 static void exynos5420_set_mmc_clk(int dev_index, unsigned int div)
899 {
900         struct exynos5420_clock *clk =
901                 (struct exynos5420_clock *)samsung_get_base_clock();
902         unsigned int addr;
903         unsigned int shift;
904
905         /*
906          * CLK_DIV_FSYS1
907          * MMC0_RATIO [9:0]
908          * MMC1_RATIO [19:10]
909          * MMC2_RATIO [29:20]
910          */
911         addr = (unsigned int)&clk->div_fsys1;
912         shift = dev_index * 10;
913
914         clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift);
915 }
916
917 /* get_lcd_clk: return lcd clock frequency */
918 static unsigned long exynos4_get_lcd_clk(void)
919 {
920         struct exynos4_clock *clk =
921                 (struct exynos4_clock *)samsung_get_base_clock();
922         unsigned long pclk, sclk;
923         unsigned int sel;
924         unsigned int ratio;
925
926         /*
927          * CLK_SRC_LCD0
928          * FIMD0_SEL [3:0]
929          */
930         sel = readl(&clk->src_lcd0);
931         sel = sel & 0xf;
932
933         /*
934          * 0x6: SCLK_MPLL
935          * 0x7: SCLK_EPLL
936          * 0x8: SCLK_VPLL
937          */
938         if (sel == 0x6)
939                 sclk = get_pll_clk(MPLL);
940         else if (sel == 0x7)
941                 sclk = get_pll_clk(EPLL);
942         else if (sel == 0x8)
943                 sclk = get_pll_clk(VPLL);
944         else
945                 return 0;
946
947         /*
948          * CLK_DIV_LCD0
949          * FIMD0_RATIO [3:0]
950          */
951         ratio = readl(&clk->div_lcd0);
952         ratio = ratio & 0xf;
953
954         pclk = sclk / (ratio + 1);
955
956         return pclk;
957 }
958
959 /* get_lcd_clk: return lcd clock frequency */
960 static unsigned long exynos5_get_lcd_clk(void)
961 {
962         struct exynos5_clock *clk =
963                 (struct exynos5_clock *)samsung_get_base_clock();
964         unsigned long pclk, sclk;
965         unsigned int sel;
966         unsigned int ratio;
967
968         /*
969          * CLK_SRC_LCD0
970          * FIMD0_SEL [3:0]
971          */
972         sel = readl(&clk->src_disp1_0);
973         sel = sel & 0xf;
974
975         /*
976          * 0x6: SCLK_MPLL
977          * 0x7: SCLK_EPLL
978          * 0x8: SCLK_VPLL
979          */
980         if (sel == 0x6)
981                 sclk = get_pll_clk(MPLL);
982         else if (sel == 0x7)
983                 sclk = get_pll_clk(EPLL);
984         else if (sel == 0x8)
985                 sclk = get_pll_clk(VPLL);
986         else
987                 return 0;
988
989         /*
990          * CLK_DIV_LCD0
991          * FIMD0_RATIO [3:0]
992          */
993         ratio = readl(&clk->div_disp1_0);
994         ratio = ratio & 0xf;
995
996         pclk = sclk / (ratio + 1);
997
998         return pclk;
999 }
1000
1001 static unsigned long exynos5420_get_lcd_clk(void)
1002 {
1003         struct exynos5420_clock *clk =
1004                 (struct exynos5420_clock *)samsung_get_base_clock();
1005         unsigned long pclk, sclk;
1006         unsigned int sel;
1007         unsigned int ratio;
1008
1009         /*
1010          * CLK_SRC_DISP10
1011          * FIMD1_SEL [4]
1012          * 0: SCLK_RPLL
1013          * 1: SCLK_SPLL
1014          */
1015         sel = readl(&clk->src_disp10);
1016         sel &= (1 << 4);
1017
1018         if (sel)
1019                 sclk = get_pll_clk(SPLL);
1020         else
1021                 sclk = get_pll_clk(RPLL);
1022
1023         /*
1024          * CLK_DIV_DISP10
1025          * FIMD1_RATIO [3:0]
1026          */
1027         ratio = readl(&clk->div_disp10);
1028         ratio = ratio & 0xf;
1029
1030         pclk = sclk / (ratio + 1);
1031
1032         return pclk;
1033 }
1034
1035 void exynos4_set_lcd_clk(void)
1036 {
1037         struct exynos4_clock *clk =
1038             (struct exynos4_clock *)samsung_get_base_clock();
1039
1040         /*
1041          * CLK_GATE_BLOCK
1042          * CLK_CAM      [0]
1043          * CLK_TV       [1]
1044          * CLK_MFC      [2]
1045          * CLK_G3D      [3]
1046          * CLK_LCD0     [4]
1047          * CLK_LCD1     [5]
1048          * CLK_GPS      [7]
1049          */
1050         setbits_le32(&clk->gate_block, 1 << 4);
1051
1052         /*
1053          * CLK_SRC_LCD0
1054          * FIMD0_SEL            [3:0]
1055          * MDNIE0_SEL           [7:4]
1056          * MDNIE_PWM0_SEL       [8:11]
1057          * MIPI0_SEL            [12:15]
1058          * set lcd0 src clock 0x6: SCLK_MPLL
1059          */
1060         clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6);
1061
1062         /*
1063          * CLK_GATE_IP_LCD0
1064          * CLK_FIMD0            [0]
1065          * CLK_MIE0             [1]
1066          * CLK_MDNIE0           [2]
1067          * CLK_DSIM0            [3]
1068          * CLK_SMMUFIMD0        [4]
1069          * CLK_PPMULCD0         [5]
1070          * Gating all clocks for FIMD0
1071          */
1072         setbits_le32(&clk->gate_ip_lcd0, 1 << 0);
1073
1074         /*
1075          * CLK_DIV_LCD0
1076          * FIMD0_RATIO          [3:0]
1077          * MDNIE0_RATIO         [7:4]
1078          * MDNIE_PWM0_RATIO     [11:8]
1079          * MDNIE_PWM_PRE_RATIO  [15:12]
1080          * MIPI0_RATIO          [19:16]
1081          * MIPI0_PRE_RATIO      [23:20]
1082          * set fimd ratio
1083          */
1084         clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1);
1085 }
1086
1087 void exynos5_set_lcd_clk(void)
1088 {
1089         struct exynos5_clock *clk =
1090             (struct exynos5_clock *)samsung_get_base_clock();
1091
1092         /*
1093          * CLK_GATE_BLOCK
1094          * CLK_CAM      [0]
1095          * CLK_TV       [1]
1096          * CLK_MFC      [2]
1097          * CLK_G3D      [3]
1098          * CLK_LCD0     [4]
1099          * CLK_LCD1     [5]
1100          * CLK_GPS      [7]
1101          */
1102         setbits_le32(&clk->gate_block, 1 << 4);
1103
1104         /*
1105          * CLK_SRC_LCD0
1106          * FIMD0_SEL            [3:0]
1107          * MDNIE0_SEL           [7:4]
1108          * MDNIE_PWM0_SEL       [8:11]
1109          * MIPI0_SEL            [12:15]
1110          * set lcd0 src clock 0x6: SCLK_MPLL
1111          */
1112         clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6);
1113
1114         /*
1115          * CLK_GATE_IP_LCD0
1116          * CLK_FIMD0            [0]
1117          * CLK_MIE0             [1]
1118          * CLK_MDNIE0           [2]
1119          * CLK_DSIM0            [3]
1120          * CLK_SMMUFIMD0        [4]
1121          * CLK_PPMULCD0         [5]
1122          * Gating all clocks for FIMD0
1123          */
1124         setbits_le32(&clk->gate_ip_disp1, 1 << 0);
1125
1126         /*
1127          * CLK_DIV_LCD0
1128          * FIMD0_RATIO          [3:0]
1129          * MDNIE0_RATIO         [7:4]
1130          * MDNIE_PWM0_RATIO     [11:8]
1131          * MDNIE_PWM_PRE_RATIO  [15:12]
1132          * MIPI0_RATIO          [19:16]
1133          * MIPI0_PRE_RATIO      [23:20]
1134          * set fimd ratio
1135          */
1136         clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0);
1137 }
1138
1139 void exynos5420_set_lcd_clk(void)
1140 {
1141         struct exynos5420_clock *clk =
1142                 (struct exynos5420_clock *)samsung_get_base_clock();
1143         unsigned int cfg;
1144
1145         /*
1146          * CLK_SRC_DISP10
1147          * FIMD1_SEL [4]
1148          * 0: SCLK_RPLL
1149          * 1: SCLK_SPLL
1150          */
1151         cfg = readl(&clk->src_disp10);
1152         cfg &= ~(0x1 << 4);
1153         cfg |= (0 << 4);
1154         writel(cfg, &clk->src_disp10);
1155
1156         /*
1157          * CLK_DIV_DISP10
1158          * FIMD1_RATIO          [3:0]
1159          */
1160         cfg = readl(&clk->div_disp10);
1161         cfg &= ~(0xf << 0);
1162         cfg |= (0 << 0);
1163         writel(cfg, &clk->div_disp10);
1164 }
1165
1166 void exynos4_set_mipi_clk(void)
1167 {
1168         struct exynos4_clock *clk =
1169             (struct exynos4_clock *)samsung_get_base_clock();
1170
1171         /*
1172          * CLK_SRC_LCD0
1173          * FIMD0_SEL            [3:0]
1174          * MDNIE0_SEL           [7:4]
1175          * MDNIE_PWM0_SEL       [8:11]
1176          * MIPI0_SEL            [12:15]
1177          * set mipi0 src clock 0x6: SCLK_MPLL
1178          */
1179         clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12);
1180
1181         /*
1182          * CLK_SRC_MASK_LCD0
1183          * FIMD0_MASK           [0]
1184          * MDNIE0_MASK          [4]
1185          * MDNIE_PWM0_MASK      [8]
1186          * MIPI0_MASK           [12]
1187          * set src mask mipi0 0x1: Unmask
1188          */
1189         setbits_le32(&clk->src_mask_lcd0, 0x1 << 12);
1190
1191         /*
1192          * CLK_GATE_IP_LCD0
1193          * CLK_FIMD0            [0]
1194          * CLK_MIE0             [1]
1195          * CLK_MDNIE0           [2]
1196          * CLK_DSIM0            [3]
1197          * CLK_SMMUFIMD0        [4]
1198          * CLK_PPMULCD0         [5]
1199          * Gating all clocks for MIPI0
1200          */
1201         setbits_le32(&clk->gate_ip_lcd0, 1 << 3);
1202
1203         /*
1204          * CLK_DIV_LCD0
1205          * FIMD0_RATIO          [3:0]
1206          * MDNIE0_RATIO         [7:4]
1207          * MDNIE_PWM0_RATIO     [11:8]
1208          * MDNIE_PWM_PRE_RATIO  [15:12]
1209          * MIPI0_RATIO          [19:16]
1210          * MIPI0_PRE_RATIO      [23:20]
1211          * set mipi ratio
1212          */
1213         clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16);
1214 }
1215
1216 int exynos5_set_epll_clk(unsigned long rate)
1217 {
1218         unsigned int epll_con, epll_con_k;
1219         unsigned int i;
1220         unsigned int lockcnt;
1221         unsigned int start;
1222         struct exynos5_clock *clk =
1223                 (struct exynos5_clock *)samsung_get_base_clock();
1224
1225         epll_con = readl(&clk->epll_con0);
1226         epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1227                         EPLL_CON0_LOCK_DET_EN_SHIFT) |
1228                 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1229                 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1230                 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1231
1232         for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1233                 if (exynos5_epll_div[i].freq_out == rate)
1234                         break;
1235         }
1236
1237         if (i == ARRAY_SIZE(exynos5_epll_div))
1238                 return -1;
1239
1240         epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1241         epll_con |= exynos5_epll_div[i].en_lock_det <<
1242                                 EPLL_CON0_LOCK_DET_EN_SHIFT;
1243         epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1244         epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1245         epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1246
1247         /*
1248          * Required period ( in cycles) to genarate a stable clock output.
1249          * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1250          * frequency input (as per spec)
1251          */
1252         lockcnt = 3000 * exynos5_epll_div[i].p_div;
1253
1254         writel(lockcnt, &clk->epll_lock);
1255         writel(epll_con, &clk->epll_con0);
1256         writel(epll_con_k, &clk->epll_con1);
1257
1258         start = get_timer(0);
1259
1260          while (!(readl(&clk->epll_con0) &
1261                         (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1262                 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1263                         debug("%s: Timeout waiting for EPLL lock\n", __func__);
1264                         return -1;
1265                 }
1266         }
1267         return 0;
1268 }
1269
1270 int exynos5_set_i2s_clk_source(unsigned int i2s_id)
1271 {
1272         struct exynos5_clock *clk =
1273                 (struct exynos5_clock *)samsung_get_base_clock();
1274         unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
1275
1276         if (i2s_id == 0) {
1277                 setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
1278                 clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
1279                                 (CLK_SRC_SCLK_EPLL));
1280                 setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
1281         } else if (i2s_id == 1) {
1282                 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1283                                 (CLK_SRC_SCLK_EPLL));
1284         } else {
1285                 return -1;
1286         }
1287         return 0;
1288 }
1289
1290 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
1291                                   unsigned int dst_frq,
1292                                   unsigned int i2s_id)
1293 {
1294         struct exynos5_clock *clk =
1295                 (struct exynos5_clock *)samsung_get_base_clock();
1296         unsigned int div;
1297
1298         if ((dst_frq == 0) || (src_frq == 0)) {
1299                 debug("%s: Invalid requency input for prescaler\n", __func__);
1300                 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1301                 return -1;
1302         }
1303
1304         div = (src_frq / dst_frq);
1305         if (i2s_id == 0) {
1306                 if (div > AUDIO_0_RATIO_MASK) {
1307                         debug("%s: Frequency ratio is out of range\n",
1308                               __func__);
1309                         debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1310                         return -1;
1311                 }
1312                 clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
1313                                 (div & AUDIO_0_RATIO_MASK));
1314         } else if(i2s_id == 1) {
1315                 if (div > AUDIO_1_RATIO_MASK) {
1316                         debug("%s: Frequency ratio is out of range\n",
1317                               __func__);
1318                         debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1319                         return -1;
1320                 }
1321                 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1322                                 (div & AUDIO_1_RATIO_MASK));
1323         } else {
1324                 return -1;
1325         }
1326         return 0;
1327 }
1328
1329 /**
1330  * Linearly searches for the most accurate main and fine stage clock scalars
1331  * (divisors) for a specified target frequency and scalar bit sizes by checking
1332  * all multiples of main_scalar_bits values. Will always return scalars up to or
1333  * slower than target.
1334  *
1335  * @param main_scalar_bits      Number of main scalar bits, must be > 0 and < 32
1336  * @param fine_scalar_bits      Number of fine scalar bits, must be > 0 and < 32
1337  * @param input_freq            Clock frequency to be scaled in Hz
1338  * @param target_freq           Desired clock frequency in Hz
1339  * @param best_fine_scalar      Pointer to store the fine stage divisor
1340  *
1341  * @return best_main_scalar     Main scalar for desired frequency or -1 if none
1342  * found
1343  */
1344 static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1345         unsigned int fine_scalar_bits, unsigned int input_rate,
1346         unsigned int target_rate, unsigned int *best_fine_scalar)
1347 {
1348         int i;
1349         int best_main_scalar = -1;
1350         unsigned int best_error = target_rate;
1351         const unsigned int cap = (1 << fine_scalar_bits) - 1;
1352         const unsigned int loops = 1 << main_scaler_bits;
1353
1354         debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1355                         target_rate, cap);
1356
1357         assert(best_fine_scalar != NULL);
1358         assert(main_scaler_bits <= fine_scalar_bits);
1359
1360         *best_fine_scalar = 1;
1361
1362         if (input_rate == 0 || target_rate == 0)
1363                 return -1;
1364
1365         if (target_rate >= input_rate)
1366                 return 1;
1367
1368         for (i = 1; i <= loops; i++) {
1369                 const unsigned int effective_div =
1370                         max(min(input_rate / i / target_rate, cap), 1U);
1371                 const unsigned int effective_rate = input_rate / i /
1372                                                         effective_div;
1373                 const int error = target_rate - effective_rate;
1374
1375                 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1376                                 effective_rate, error);
1377
1378                 if (error >= 0 && error <= best_error) {
1379                         best_error = error;
1380                         best_main_scalar = i;
1381                         *best_fine_scalar = effective_div;
1382                 }
1383         }
1384
1385         return best_main_scalar;
1386 }
1387
1388 static int exynos5_set_spi_clk(enum periph_id periph_id,
1389                                         unsigned int rate)
1390 {
1391         struct exynos5_clock *clk =
1392                 (struct exynos5_clock *)samsung_get_base_clock();
1393         int main;
1394         unsigned int fine;
1395         unsigned shift, pre_shift;
1396         unsigned mask = 0xff;
1397         u32 *reg;
1398
1399         main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1400         if (main < 0) {
1401                 debug("%s: Cannot set clock rate for periph %d",
1402                                 __func__, periph_id);
1403                 return -1;
1404         }
1405         main = main - 1;
1406         fine = fine - 1;
1407
1408         switch (periph_id) {
1409         case PERIPH_ID_SPI0:
1410                 reg = &clk->div_peric1;
1411                 shift = 0;
1412                 pre_shift = 8;
1413                 break;
1414         case PERIPH_ID_SPI1:
1415                 reg = &clk->div_peric1;
1416                 shift = 16;
1417                 pre_shift = 24;
1418                 break;
1419         case PERIPH_ID_SPI2:
1420                 reg = &clk->div_peric2;
1421                 shift = 0;
1422                 pre_shift = 8;
1423                 break;
1424         case PERIPH_ID_SPI3:
1425                 reg = &clk->sclk_div_isp;
1426                 shift = 0;
1427                 pre_shift = 4;
1428                 break;
1429         case PERIPH_ID_SPI4:
1430                 reg = &clk->sclk_div_isp;
1431                 shift = 12;
1432                 pre_shift = 16;
1433                 break;
1434         default:
1435                 debug("%s: Unsupported peripheral ID %d\n", __func__,
1436                       periph_id);
1437                 return -1;
1438         }
1439         clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1440         clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1441
1442         return 0;
1443 }
1444
1445 static int exynos5420_set_spi_clk(enum periph_id periph_id,
1446                                         unsigned int rate)
1447 {
1448         struct exynos5420_clock *clk =
1449                 (struct exynos5420_clock *)samsung_get_base_clock();
1450         int main;
1451         unsigned int fine;
1452         unsigned shift, pre_shift;
1453         unsigned div_mask = 0xf, pre_div_mask = 0xff;
1454         u32 *reg;
1455         u32 *pre_reg;
1456
1457         main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1458         if (main < 0) {
1459                 debug("%s: Cannot set clock rate for periph %d",
1460                       __func__, periph_id);
1461                 return -1;
1462         }
1463         main = main - 1;
1464         fine = fine - 1;
1465
1466         switch (periph_id) {
1467         case PERIPH_ID_SPI0:
1468                 reg = &clk->div_peric1;
1469                 shift = 20;
1470                 pre_reg = &clk->div_peric4;
1471                 pre_shift = 8;
1472                 break;
1473         case PERIPH_ID_SPI1:
1474                 reg = &clk->div_peric1;
1475                 shift = 24;
1476                 pre_reg = &clk->div_peric4;
1477                 pre_shift = 16;
1478                 break;
1479         case PERIPH_ID_SPI2:
1480                 reg = &clk->div_peric1;
1481                 shift = 28;
1482                 pre_reg = &clk->div_peric4;
1483                 pre_shift = 24;
1484                 break;
1485         case PERIPH_ID_SPI3:
1486                 reg = &clk->div_isp1;
1487                 shift = 16;
1488                 pre_reg = &clk->div_isp1;
1489                 pre_shift = 0;
1490                 break;
1491         case PERIPH_ID_SPI4:
1492                 reg = &clk->div_isp1;
1493                 shift = 20;
1494                 pre_reg = &clk->div_isp1;
1495                 pre_shift = 8;
1496                 break;
1497         default:
1498                 debug("%s: Unsupported peripheral ID %d\n", __func__,
1499                       periph_id);
1500                 return -1;
1501         }
1502
1503         clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
1504         clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
1505                         (fine & pre_div_mask) << pre_shift);
1506
1507         return 0;
1508 }
1509
1510 static unsigned long exynos4_get_i2c_clk(void)
1511 {
1512         struct exynos4_clock *clk =
1513                 (struct exynos4_clock *)samsung_get_base_clock();
1514         unsigned long sclk, aclk_100;
1515         unsigned int ratio;
1516
1517         sclk = get_pll_clk(APLL);
1518
1519         ratio = (readl(&clk->div_top)) >> 4;
1520         ratio &= 0xf;
1521         aclk_100 = sclk / (ratio + 1);
1522         return aclk_100;
1523 }
1524
1525 unsigned long get_pll_clk(int pllreg)
1526 {
1527         if (cpu_is_exynos5()) {
1528                 if (proid_is_exynos5420() || proid_is_exynos5800())
1529                         return exynos542x_get_pll_clk(pllreg);
1530                 return exynos5_get_pll_clk(pllreg);
1531         } else {
1532                 if (proid_is_exynos4412())
1533                         return exynos4x12_get_pll_clk(pllreg);
1534                 return exynos4_get_pll_clk(pllreg);
1535         }
1536 }
1537
1538 unsigned long get_arm_clk(void)
1539 {
1540         if (cpu_is_exynos5())
1541                 return exynos5_get_arm_clk();
1542         else {
1543                 if (proid_is_exynos4412())
1544                         return exynos4x12_get_arm_clk();
1545                 return exynos4_get_arm_clk();
1546         }
1547 }
1548
1549 unsigned long get_i2c_clk(void)
1550 {
1551         if (cpu_is_exynos5()) {
1552                 return clock_get_periph_rate(PERIPH_ID_I2C0);
1553         } else if (cpu_is_exynos4()) {
1554                 return exynos4_get_i2c_clk();
1555         } else {
1556                 debug("I2C clock is not set for this CPU\n");
1557                 return 0;
1558         }
1559 }
1560
1561 unsigned long get_pwm_clk(void)
1562 {
1563         if (cpu_is_exynos5()) {
1564                 return clock_get_periph_rate(PERIPH_ID_PWM0);
1565         } else {
1566                 if (proid_is_exynos4412())
1567                         return exynos4x12_get_pwm_clk();
1568                 return exynos4_get_pwm_clk();
1569         }
1570 }
1571
1572 unsigned long get_uart_clk(int dev_index)
1573 {
1574         enum periph_id id;
1575
1576         switch (dev_index) {
1577         case 0:
1578                 id = PERIPH_ID_UART0;
1579                 break;
1580         case 1:
1581                 id = PERIPH_ID_UART1;
1582                 break;
1583         case 2:
1584                 id = PERIPH_ID_UART2;
1585                 break;
1586         case 3:
1587                 id = PERIPH_ID_UART3;
1588                 break;
1589         default:
1590                 debug("%s: invalid UART index %d", __func__, dev_index);
1591                 return -1;
1592         }
1593
1594         if (cpu_is_exynos5()) {
1595                 return clock_get_periph_rate(id);
1596         } else {
1597                 if (proid_is_exynos4412())
1598                         return exynos4x12_get_uart_clk(dev_index);
1599                 return exynos4_get_uart_clk(dev_index);
1600         }
1601 }
1602
1603 unsigned long get_mmc_clk(int dev_index)
1604 {
1605         enum periph_id id;
1606
1607         switch (dev_index) {
1608         case 0:
1609                 id = PERIPH_ID_SDMMC0;
1610                 break;
1611         case 1:
1612                 id = PERIPH_ID_SDMMC1;
1613                 break;
1614         case 2:
1615                 id = PERIPH_ID_SDMMC2;
1616                 break;
1617         case 3:
1618                 id = PERIPH_ID_SDMMC3;
1619                 break;
1620         default:
1621                 debug("%s: invalid MMC index %d", __func__, dev_index);
1622                 return -1;
1623         }
1624
1625         if (cpu_is_exynos5()) {
1626                 return clock_get_periph_rate(id);
1627         } else {
1628                 return exynos4_get_mmc_clk(dev_index);
1629         }
1630 }
1631
1632 void set_mmc_clk(int dev_index, unsigned int div)
1633 {
1634         /* If want to set correct value, it needs to substract one from div.*/
1635         if (div > 0)
1636                 div -= 1;
1637
1638         if (cpu_is_exynos5()) {
1639                 if (proid_is_exynos5420() || proid_is_exynos5800())
1640                         exynos5420_set_mmc_clk(dev_index, div);
1641                 else
1642                         exynos5_set_mmc_clk(dev_index, div);
1643         } else {
1644                 exynos4_set_mmc_clk(dev_index, div);
1645         }
1646 }
1647
1648 unsigned long get_lcd_clk(void)
1649 {
1650         if (cpu_is_exynos4())
1651                 return exynos4_get_lcd_clk();
1652         else {
1653                 if (proid_is_exynos5420() || proid_is_exynos5800())
1654                         return exynos5420_get_lcd_clk();
1655                 else
1656                         return exynos5_get_lcd_clk();
1657         }
1658 }
1659
1660 void set_lcd_clk(void)
1661 {
1662         if (cpu_is_exynos4())
1663                 exynos4_set_lcd_clk();
1664         else {
1665                 if (proid_is_exynos5250())
1666                         exynos5_set_lcd_clk();
1667                 else if (proid_is_exynos5420() || proid_is_exynos5800())
1668                         exynos5420_set_lcd_clk();
1669         }
1670 }
1671
1672 void set_mipi_clk(void)
1673 {
1674         if (cpu_is_exynos4())
1675                 exynos4_set_mipi_clk();
1676 }
1677
1678 int set_spi_clk(int periph_id, unsigned int rate)
1679 {
1680         if (cpu_is_exynos5()) {
1681                 if (proid_is_exynos5420() || proid_is_exynos5800())
1682                         return exynos5420_set_spi_clk(periph_id, rate);
1683                 return exynos5_set_spi_clk(periph_id, rate);
1684         } else {
1685                 return 0;
1686         }
1687 }
1688
1689 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
1690                           unsigned int i2s_id)
1691 {
1692         if (cpu_is_exynos5())
1693                 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
1694         else
1695                 return 0;
1696 }
1697
1698 int set_i2s_clk_source(unsigned int i2s_id)
1699 {
1700         if (cpu_is_exynos5())
1701                 return exynos5_set_i2s_clk_source(i2s_id);
1702         else
1703                 return 0;
1704 }
1705
1706 int set_epll_clk(unsigned long rate)
1707 {
1708         if (cpu_is_exynos5())
1709                 return exynos5_set_epll_clk(rate);
1710         else
1711                 return 0;
1712 }