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