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