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