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