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