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