]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/exynos/clock.c
Merge branch 'agust@denx.de' of git://git.denx.de/u-boot-staging
[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
29 /* exynos4: return pll clock frequency */
30 static unsigned long exynos4_get_pll_clk(int pllreg)
31 {
32         struct exynos4_clock *clk =
33                 (struct exynos4_clock *)samsung_get_base_clock();
34         unsigned long r, m, p, s, k = 0, mask, fout;
35         unsigned int freq;
36
37         switch (pllreg) {
38         case APLL:
39                 r = readl(&clk->apll_con0);
40                 break;
41         case MPLL:
42                 r = readl(&clk->mpll_con0);
43                 break;
44         case EPLL:
45                 r = readl(&clk->epll_con0);
46                 k = readl(&clk->epll_con1);
47                 break;
48         case VPLL:
49                 r = readl(&clk->vpll_con0);
50                 k = readl(&clk->vpll_con1);
51                 break;
52         default:
53                 printf("Unsupported PLL (%d)\n", pllreg);
54                 return 0;
55         }
56
57         /*
58          * APLL_CON: MIDV [25:16]
59          * MPLL_CON: MIDV [25:16]
60          * EPLL_CON: MIDV [24:16]
61          * VPLL_CON: MIDV [24:16]
62          */
63         if (pllreg == APLL || pllreg == MPLL)
64                 mask = 0x3ff;
65         else
66                 mask = 0x1ff;
67
68         m = (r >> 16) & mask;
69
70         /* PDIV [13:8] */
71         p = (r >> 8) & 0x3f;
72         /* SDIV [2:0] */
73         s = r & 0x7;
74
75         freq = CONFIG_SYS_CLK_FREQ;
76
77         if (pllreg == EPLL) {
78                 k = k & 0xffff;
79                 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
80                 fout = (m + k / 65536) * (freq / (p * (1 << s)));
81         } else if (pllreg == VPLL) {
82                 k = k & 0xfff;
83                 /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
84                 fout = (m + k / 1024) * (freq / (p * (1 << s)));
85         } else {
86                 if (s < 1)
87                         s = 1;
88                 /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
89                 fout = m * (freq / (p * (1 << (s - 1))));
90         }
91
92         return fout;
93 }
94
95 /* exynos5: return pll clock frequency */
96 static unsigned long exynos5_get_pll_clk(int pllreg)
97 {
98         struct exynos5_clock *clk =
99                 (struct exynos5_clock *)samsung_get_base_clock();
100         unsigned long r, m, p, s, k = 0, mask, fout;
101         unsigned int freq, pll_div2_sel, fout_sel;
102
103         switch (pllreg) {
104         case APLL:
105                 r = readl(&clk->apll_con0);
106                 break;
107         case MPLL:
108                 r = readl(&clk->mpll_con0);
109                 break;
110         case EPLL:
111                 r = readl(&clk->epll_con0);
112                 k = readl(&clk->epll_con1);
113                 break;
114         case VPLL:
115                 r = readl(&clk->vpll_con0);
116                 k = readl(&clk->vpll_con1);
117                 break;
118         case BPLL:
119                 r = readl(&clk->bpll_con0);
120                 break;
121         default:
122                 printf("Unsupported PLL (%d)\n", pllreg);
123                 return 0;
124         }
125
126         /*
127          * APLL_CON: MIDV [25:16]
128          * MPLL_CON: MIDV [25:16]
129          * EPLL_CON: MIDV [24:16]
130          * VPLL_CON: MIDV [24:16]
131          * BPLL_CON: MIDV [25:16]
132          */
133         if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL)
134                 mask = 0x3ff;
135         else
136                 mask = 0x1ff;
137
138         m = (r >> 16) & mask;
139
140         /* PDIV [13:8] */
141         p = (r >> 8) & 0x3f;
142         /* SDIV [2:0] */
143         s = r & 0x7;
144
145         freq = CONFIG_SYS_CLK_FREQ;
146
147         if (pllreg == EPLL) {
148                 k = k & 0xffff;
149                 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
150                 fout = (m + k / 65536) * (freq / (p * (1 << s)));
151         } else if (pllreg == VPLL) {
152                 k = k & 0xfff;
153                 /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
154                 fout = (m + k / 1024) * (freq / (p * (1 << s)));
155         } else {
156                 if (s < 1)
157                         s = 1;
158                 /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
159                 fout = m * (freq / (p * (1 << (s - 1))));
160         }
161
162         /* According to the user manual, in EVT1 MPLL and BPLL always gives
163          * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
164         if (pllreg == MPLL || pllreg == BPLL) {
165                 pll_div2_sel = readl(&clk->pll_div2_sel);
166
167                 switch (pllreg) {
168                 case MPLL:
169                         fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
170                                         & MPLL_FOUT_SEL_MASK;
171                         break;
172                 case BPLL:
173                         fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
174                                         & BPLL_FOUT_SEL_MASK;
175                         break;
176                 default:
177                         fout_sel = -1;
178                         break;
179                 }
180
181                 if (fout_sel == 0)
182                         fout /= 2;
183         }
184
185         return fout;
186 }
187
188 /* exynos4: return ARM clock frequency */
189 static unsigned long exynos4_get_arm_clk(void)
190 {
191         struct exynos4_clock *clk =
192                 (struct exynos4_clock *)samsung_get_base_clock();
193         unsigned long div;
194         unsigned long armclk;
195         unsigned int core_ratio;
196         unsigned int core2_ratio;
197
198         div = readl(&clk->div_cpu0);
199
200         /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
201         core_ratio = (div >> 0) & 0x7;
202         core2_ratio = (div >> 28) & 0x7;
203
204         armclk = get_pll_clk(APLL) / (core_ratio + 1);
205         armclk /= (core2_ratio + 1);
206
207         return armclk;
208 }
209
210 /* exynos5: return ARM clock frequency */
211 static unsigned long exynos5_get_arm_clk(void)
212 {
213         struct exynos5_clock *clk =
214                 (struct exynos5_clock *)samsung_get_base_clock();
215         unsigned long div;
216         unsigned long armclk;
217         unsigned int arm_ratio;
218         unsigned int arm2_ratio;
219
220         div = readl(&clk->div_cpu0);
221
222         /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
223         arm_ratio = (div >> 0) & 0x7;
224         arm2_ratio = (div >> 28) & 0x7;
225
226         armclk = get_pll_clk(APLL) / (arm_ratio + 1);
227         armclk /= (arm2_ratio + 1);
228
229         return armclk;
230 }
231
232 /* exynos4: return pwm clock frequency */
233 static unsigned long exynos4_get_pwm_clk(void)
234 {
235         struct exynos4_clock *clk =
236                 (struct exynos4_clock *)samsung_get_base_clock();
237         unsigned long pclk, sclk;
238         unsigned int sel;
239         unsigned int ratio;
240
241         if (s5p_get_cpu_rev() == 0) {
242                 /*
243                  * CLK_SRC_PERIL0
244                  * PWM_SEL [27:24]
245                  */
246                 sel = readl(&clk->src_peril0);
247                 sel = (sel >> 24) & 0xf;
248
249                 if (sel == 0x6)
250                         sclk = get_pll_clk(MPLL);
251                 else if (sel == 0x7)
252                         sclk = get_pll_clk(EPLL);
253                 else if (sel == 0x8)
254                         sclk = get_pll_clk(VPLL);
255                 else
256                         return 0;
257
258                 /*
259                  * CLK_DIV_PERIL3
260                  * PWM_RATIO [3:0]
261                  */
262                 ratio = readl(&clk->div_peril3);
263                 ratio = ratio & 0xf;
264         } else if (s5p_get_cpu_rev() == 1) {
265                 sclk = get_pll_clk(MPLL);
266                 ratio = 8;
267         } else
268                 return 0;
269
270         pclk = sclk / (ratio + 1);
271
272         return pclk;
273 }
274
275 /* exynos5: return pwm clock frequency */
276 static unsigned long exynos5_get_pwm_clk(void)
277 {
278         struct exynos5_clock *clk =
279                 (struct exynos5_clock *)samsung_get_base_clock();
280         unsigned long pclk, sclk;
281         unsigned int ratio;
282
283         /*
284          * CLK_DIV_PERIC3
285          * PWM_RATIO [3:0]
286          */
287         ratio = readl(&clk->div_peric3);
288         ratio = ratio & 0xf;
289         sclk = get_pll_clk(MPLL);
290
291         pclk = sclk / (ratio + 1);
292
293         return pclk;
294 }
295
296 /* exynos4: return uart clock frequency */
297 static unsigned long exynos4_get_uart_clk(int dev_index)
298 {
299         struct exynos4_clock *clk =
300                 (struct exynos4_clock *)samsung_get_base_clock();
301         unsigned long uclk, sclk;
302         unsigned int sel;
303         unsigned int ratio;
304
305         /*
306          * CLK_SRC_PERIL0
307          * UART0_SEL [3:0]
308          * UART1_SEL [7:4]
309          * UART2_SEL [8:11]
310          * UART3_SEL [12:15]
311          * UART4_SEL [16:19]
312          * UART5_SEL [23:20]
313          */
314         sel = readl(&clk->src_peril0);
315         sel = (sel >> (dev_index << 2)) & 0xf;
316
317         if (sel == 0x6)
318                 sclk = get_pll_clk(MPLL);
319         else if (sel == 0x7)
320                 sclk = get_pll_clk(EPLL);
321         else if (sel == 0x8)
322                 sclk = get_pll_clk(VPLL);
323         else
324                 return 0;
325
326         /*
327          * CLK_DIV_PERIL0
328          * UART0_RATIO [3:0]
329          * UART1_RATIO [7:4]
330          * UART2_RATIO [8:11]
331          * UART3_RATIO [12:15]
332          * UART4_RATIO [16:19]
333          * UART5_RATIO [23:20]
334          */
335         ratio = readl(&clk->div_peril0);
336         ratio = (ratio >> (dev_index << 2)) & 0xf;
337
338         uclk = sclk / (ratio + 1);
339
340         return uclk;
341 }
342
343 /* exynos5: return uart clock frequency */
344 static unsigned long exynos5_get_uart_clk(int dev_index)
345 {
346         struct exynos5_clock *clk =
347                 (struct exynos5_clock *)samsung_get_base_clock();
348         unsigned long uclk, sclk;
349         unsigned int sel;
350         unsigned int ratio;
351
352         /*
353          * CLK_SRC_PERIC0
354          * UART0_SEL [3:0]
355          * UART1_SEL [7:4]
356          * UART2_SEL [8:11]
357          * UART3_SEL [12:15]
358          * UART4_SEL [16:19]
359          * UART5_SEL [23:20]
360          */
361         sel = readl(&clk->src_peric0);
362         sel = (sel >> (dev_index << 2)) & 0xf;
363
364         if (sel == 0x6)
365                 sclk = get_pll_clk(MPLL);
366         else if (sel == 0x7)
367                 sclk = get_pll_clk(EPLL);
368         else if (sel == 0x8)
369                 sclk = get_pll_clk(VPLL);
370         else
371                 return 0;
372
373         /*
374          * CLK_DIV_PERIC0
375          * UART0_RATIO [3:0]
376          * UART1_RATIO [7:4]
377          * UART2_RATIO [8:11]
378          * UART3_RATIO [12:15]
379          * UART4_RATIO [16:19]
380          * UART5_RATIO [23:20]
381          */
382         ratio = readl(&clk->div_peric0);
383         ratio = (ratio >> (dev_index << 2)) & 0xf;
384
385         uclk = sclk / (ratio + 1);
386
387         return uclk;
388 }
389
390 /* exynos4: set the mmc clock */
391 static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
392 {
393         struct exynos4_clock *clk =
394                 (struct exynos4_clock *)samsung_get_base_clock();
395         unsigned int addr;
396         unsigned int val;
397
398         /*
399          * CLK_DIV_FSYS1
400          * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
401          * CLK_DIV_FSYS2
402          * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
403          */
404         if (dev_index < 2) {
405                 addr = (unsigned int)&clk->div_fsys1;
406         } else {
407                 addr = (unsigned int)&clk->div_fsys2;
408                 dev_index -= 2;
409         }
410
411         val = readl(addr);
412         val &= ~(0xff << ((dev_index << 4) + 8));
413         val |= (div & 0xff) << ((dev_index << 4) + 8);
414         writel(val, addr);
415 }
416
417 /* exynos5: set the mmc clock */
418 static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
419 {
420         struct exynos5_clock *clk =
421                 (struct exynos5_clock *)samsung_get_base_clock();
422         unsigned int addr;
423         unsigned int val;
424
425         /*
426          * CLK_DIV_FSYS1
427          * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
428          * CLK_DIV_FSYS2
429          * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
430          */
431         if (dev_index < 2) {
432                 addr = (unsigned int)&clk->div_fsys1;
433         } else {
434                 addr = (unsigned int)&clk->div_fsys2;
435                 dev_index -= 2;
436         }
437
438         val = readl(addr);
439         val &= ~(0xff << ((dev_index << 4) + 8));
440         val |= (div & 0xff) << ((dev_index << 4) + 8);
441         writel(val, addr);
442 }
443
444 /* get_lcd_clk: return lcd clock frequency */
445 static unsigned long exynos4_get_lcd_clk(void)
446 {
447         struct exynos4_clock *clk =
448                 (struct exynos4_clock *)samsung_get_base_clock();
449         unsigned long pclk, sclk;
450         unsigned int sel;
451         unsigned int ratio;
452
453         /*
454          * CLK_SRC_LCD0
455          * FIMD0_SEL [3:0]
456          */
457         sel = readl(&clk->src_lcd0);
458         sel = sel & 0xf;
459
460         /*
461          * 0x6: SCLK_MPLL
462          * 0x7: SCLK_EPLL
463          * 0x8: SCLK_VPLL
464          */
465         if (sel == 0x6)
466                 sclk = get_pll_clk(MPLL);
467         else if (sel == 0x7)
468                 sclk = get_pll_clk(EPLL);
469         else if (sel == 0x8)
470                 sclk = get_pll_clk(VPLL);
471         else
472                 return 0;
473
474         /*
475          * CLK_DIV_LCD0
476          * FIMD0_RATIO [3:0]
477          */
478         ratio = readl(&clk->div_lcd0);
479         ratio = ratio & 0xf;
480
481         pclk = sclk / (ratio + 1);
482
483         return pclk;
484 }
485
486 /* get_lcd_clk: return lcd clock frequency */
487 static unsigned long exynos5_get_lcd_clk(void)
488 {
489         struct exynos5_clock *clk =
490                 (struct exynos5_clock *)samsung_get_base_clock();
491         unsigned long pclk, sclk;
492         unsigned int sel;
493         unsigned int ratio;
494
495         /*
496          * CLK_SRC_LCD0
497          * FIMD0_SEL [3:0]
498          */
499         sel = readl(&clk->src_disp1_0);
500         sel = sel & 0xf;
501
502         /*
503          * 0x6: SCLK_MPLL
504          * 0x7: SCLK_EPLL
505          * 0x8: SCLK_VPLL
506          */
507         if (sel == 0x6)
508                 sclk = get_pll_clk(MPLL);
509         else if (sel == 0x7)
510                 sclk = get_pll_clk(EPLL);
511         else if (sel == 0x8)
512                 sclk = get_pll_clk(VPLL);
513         else
514                 return 0;
515
516         /*
517          * CLK_DIV_LCD0
518          * FIMD0_RATIO [3:0]
519          */
520         ratio = readl(&clk->div_disp1_0);
521         ratio = ratio & 0xf;
522
523         pclk = sclk / (ratio + 1);
524
525         return pclk;
526 }
527
528 void exynos4_set_lcd_clk(void)
529 {
530         struct exynos4_clock *clk =
531             (struct exynos4_clock *)samsung_get_base_clock();
532         unsigned int cfg = 0;
533
534         /*
535          * CLK_GATE_BLOCK
536          * CLK_CAM      [0]
537          * CLK_TV       [1]
538          * CLK_MFC      [2]
539          * CLK_G3D      [3]
540          * CLK_LCD0     [4]
541          * CLK_LCD1     [5]
542          * CLK_GPS      [7]
543          */
544         cfg = readl(&clk->gate_block);
545         cfg |= 1 << 4;
546         writel(cfg, &clk->gate_block);
547
548         /*
549          * CLK_SRC_LCD0
550          * FIMD0_SEL            [3:0]
551          * MDNIE0_SEL           [7:4]
552          * MDNIE_PWM0_SEL       [8:11]
553          * MIPI0_SEL            [12:15]
554          * set lcd0 src clock 0x6: SCLK_MPLL
555          */
556         cfg = readl(&clk->src_lcd0);
557         cfg &= ~(0xf);
558         cfg |= 0x6;
559         writel(cfg, &clk->src_lcd0);
560
561         /*
562          * CLK_GATE_IP_LCD0
563          * CLK_FIMD0            [0]
564          * CLK_MIE0             [1]
565          * CLK_MDNIE0           [2]
566          * CLK_DSIM0            [3]
567          * CLK_SMMUFIMD0        [4]
568          * CLK_PPMULCD0         [5]
569          * Gating all clocks for FIMD0
570          */
571         cfg = readl(&clk->gate_ip_lcd0);
572         cfg |= 1 << 0;
573         writel(cfg, &clk->gate_ip_lcd0);
574
575         /*
576          * CLK_DIV_LCD0
577          * FIMD0_RATIO          [3:0]
578          * MDNIE0_RATIO         [7:4]
579          * MDNIE_PWM0_RATIO     [11:8]
580          * MDNIE_PWM_PRE_RATIO  [15:12]
581          * MIPI0_RATIO          [19:16]
582          * MIPI0_PRE_RATIO      [23:20]
583          * set fimd ratio
584          */
585         cfg &= ~(0xf);
586         cfg |= 0x1;
587         writel(cfg, &clk->div_lcd0);
588 }
589
590 void exynos5_set_lcd_clk(void)
591 {
592         struct exynos5_clock *clk =
593             (struct exynos5_clock *)samsung_get_base_clock();
594         unsigned int cfg = 0;
595
596         /*
597          * CLK_GATE_BLOCK
598          * CLK_CAM      [0]
599          * CLK_TV       [1]
600          * CLK_MFC      [2]
601          * CLK_G3D      [3]
602          * CLK_LCD0     [4]
603          * CLK_LCD1     [5]
604          * CLK_GPS      [7]
605          */
606         cfg = readl(&clk->gate_block);
607         cfg |= 1 << 4;
608         writel(cfg, &clk->gate_block);
609
610         /*
611          * CLK_SRC_LCD0
612          * FIMD0_SEL            [3:0]
613          * MDNIE0_SEL           [7:4]
614          * MDNIE_PWM0_SEL       [8:11]
615          * MIPI0_SEL            [12:15]
616          * set lcd0 src clock 0x6: SCLK_MPLL
617          */
618         cfg = readl(&clk->src_disp1_0);
619         cfg &= ~(0xf);
620         cfg |= 0x8;
621         writel(cfg, &clk->src_disp1_0);
622
623         /*
624          * CLK_GATE_IP_LCD0
625          * CLK_FIMD0            [0]
626          * CLK_MIE0             [1]
627          * CLK_MDNIE0           [2]
628          * CLK_DSIM0            [3]
629          * CLK_SMMUFIMD0        [4]
630          * CLK_PPMULCD0         [5]
631          * Gating all clocks for FIMD0
632          */
633         cfg = readl(&clk->gate_ip_disp1);
634         cfg |= 1 << 0;
635         writel(cfg, &clk->gate_ip_disp1);
636
637         /*
638          * CLK_DIV_LCD0
639          * FIMD0_RATIO          [3:0]
640          * MDNIE0_RATIO         [7:4]
641          * MDNIE_PWM0_RATIO     [11:8]
642          * MDNIE_PWM_PRE_RATIO  [15:12]
643          * MIPI0_RATIO          [19:16]
644          * MIPI0_PRE_RATIO      [23:20]
645          * set fimd ratio
646          */
647         cfg &= ~(0xf);
648         cfg |= 0x0;
649         writel(cfg, &clk->div_disp1_0);
650 }
651
652 void exynos4_set_mipi_clk(void)
653 {
654         struct exynos4_clock *clk =
655             (struct exynos4_clock *)samsung_get_base_clock();
656         unsigned int cfg = 0;
657
658         /*
659          * CLK_SRC_LCD0
660          * FIMD0_SEL            [3:0]
661          * MDNIE0_SEL           [7:4]
662          * MDNIE_PWM0_SEL       [8:11]
663          * MIPI0_SEL            [12:15]
664          * set mipi0 src clock 0x6: SCLK_MPLL
665          */
666         cfg = readl(&clk->src_lcd0);
667         cfg &= ~(0xf << 12);
668         cfg |= (0x6 << 12);
669         writel(cfg, &clk->src_lcd0);
670
671         /*
672          * CLK_SRC_MASK_LCD0
673          * FIMD0_MASK           [0]
674          * MDNIE0_MASK          [4]
675          * MDNIE_PWM0_MASK      [8]
676          * MIPI0_MASK           [12]
677          * set src mask mipi0 0x1: Unmask
678          */
679         cfg = readl(&clk->src_mask_lcd0);
680         cfg |= (0x1 << 12);
681         writel(cfg, &clk->src_mask_lcd0);
682
683         /*
684          * CLK_GATE_IP_LCD0
685          * CLK_FIMD0            [0]
686          * CLK_MIE0             [1]
687          * CLK_MDNIE0           [2]
688          * CLK_DSIM0            [3]
689          * CLK_SMMUFIMD0        [4]
690          * CLK_PPMULCD0         [5]
691          * Gating all clocks for MIPI0
692          */
693         cfg = readl(&clk->gate_ip_lcd0);
694         cfg |= 1 << 3;
695         writel(cfg, &clk->gate_ip_lcd0);
696
697         /*
698          * CLK_DIV_LCD0
699          * FIMD0_RATIO          [3:0]
700          * MDNIE0_RATIO         [7:4]
701          * MDNIE_PWM0_RATIO     [11:8]
702          * MDNIE_PWM_PRE_RATIO  [15:12]
703          * MIPI0_RATIO          [19:16]
704          * MIPI0_PRE_RATIO      [23:20]
705          * set mipi ratio
706          */
707         cfg &= ~(0xf << 16);
708         cfg |= (0x1 << 16);
709         writel(cfg, &clk->div_lcd0);
710 }
711
712 /*
713  * I2C
714  *
715  * exynos5: obtaining the I2C clock
716  */
717 static unsigned long exynos5_get_i2c_clk(void)
718 {
719         struct exynos5_clock *clk =
720                 (struct exynos5_clock *)samsung_get_base_clock();
721         unsigned long aclk_66, aclk_66_pre, sclk;
722         unsigned int ratio;
723
724         sclk = get_pll_clk(MPLL);
725
726         ratio = (readl(&clk->div_top1)) >> 24;
727         ratio &= 0x7;
728         aclk_66_pre = sclk / (ratio + 1);
729         ratio = readl(&clk->div_top0);
730         ratio &= 0x7;
731         aclk_66 = aclk_66_pre / (ratio + 1);
732         return aclk_66;
733 }
734
735 unsigned long get_pll_clk(int pllreg)
736 {
737         if (cpu_is_exynos5())
738                 return exynos5_get_pll_clk(pllreg);
739         else
740                 return exynos4_get_pll_clk(pllreg);
741 }
742
743 unsigned long get_arm_clk(void)
744 {
745         if (cpu_is_exynos5())
746                 return exynos5_get_arm_clk();
747         else
748                 return exynos4_get_arm_clk();
749 }
750
751 unsigned long get_i2c_clk(void)
752 {
753         if (cpu_is_exynos5()) {
754                 return exynos5_get_i2c_clk();
755         } else {
756                 debug("I2C clock is not set for this CPU\n");
757                 return 0;
758         }
759 }
760
761 unsigned long get_pwm_clk(void)
762 {
763         if (cpu_is_exynos5())
764                 return exynos5_get_pwm_clk();
765         else
766                 return exynos4_get_pwm_clk();
767 }
768
769 unsigned long get_uart_clk(int dev_index)
770 {
771         if (cpu_is_exynos5())
772                 return exynos5_get_uart_clk(dev_index);
773         else
774                 return exynos4_get_uart_clk(dev_index);
775 }
776
777 void set_mmc_clk(int dev_index, unsigned int div)
778 {
779         if (cpu_is_exynos5())
780                 exynos5_set_mmc_clk(dev_index, div);
781         else
782                 exynos4_set_mmc_clk(dev_index, div);
783 }
784
785 unsigned long get_lcd_clk(void)
786 {
787         if (cpu_is_exynos4())
788                 return exynos4_get_lcd_clk();
789         else
790                 return exynos5_get_lcd_clk();
791 }
792
793 void set_lcd_clk(void)
794 {
795         if (cpu_is_exynos4())
796                 exynos4_set_lcd_clk();
797         else
798                 exynos5_set_lcd_clk();
799 }
800
801 void set_mipi_clk(void)
802 {
803         if (cpu_is_exynos4())
804                 exynos4_set_mipi_clk();
805 }