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