blob: 4f3b451be9955cc6e09047b5daedbe39ea2c412f [file] [log] [blame]
Minkyu Kangb1b24682011-01-24 15:22:23 +09001/*
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
Chander Kashyap4131a772011-12-06 23:34:12 +000029/* exynos4: return pll clock frequency */
30static unsigned long exynos4_get_pll_clk(int pllreg)
Minkyu Kangb1b24682011-01-24 15:22:23 +090031{
Chander Kashyap4131a772011-12-06 23:34:12 +000032 struct exynos4_clock *clk =
33 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kangb1b24682011-01-24 15:22:23 +090034 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
Chander Kashyap6a870e12012-02-05 23:01:45 +000075 freq = CONFIG_SYS_CLK_FREQ;
Minkyu Kangb1b24682011-01-24 15:22:23 +090076
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
Chander Kashyap34076a02012-02-05 23:01:46 +000095/* exynos5: return pll clock frequency */
96static 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;
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000101 unsigned int freq, pll_div2_sel, fout_sel;
Chander Kashyap34076a02012-02-05 23:01:46 +0000102
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;
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000118 case BPLL:
119 r = readl(&clk->bpll_con0);
120 break;
Chander Kashyap34076a02012-02-05 23:01:46 +0000121 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]
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000131 * BPLL_CON: MIDV [25:16]
Chander Kashyap34076a02012-02-05 23:01:46 +0000132 */
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000133 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL)
Chander Kashyap34076a02012-02-05 23:01:46 +0000134 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
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000162 /* According to the user manual, in EVT1 MPLL and BPLL always gives
Rajeshwari Shinde7b9afce2012-07-03 20:02:57 +0000163 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000164 if (pllreg == MPLL || pllreg == BPLL) {
Rajeshwari Shinde7b9afce2012-07-03 20:02:57 +0000165 pll_div2_sel = readl(&clk->pll_div2_sel);
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000166
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;
Jaehoon Chung0fc779c2012-07-09 21:20:34 +0000176 default:
177 fout_sel = -1;
178 break;
Rajeshwari Shinde84112862012-07-03 20:02:58 +0000179 }
180
181 if (fout_sel == 0)
Rajeshwari Shinde7b9afce2012-07-03 20:02:57 +0000182 fout /= 2;
183 }
184
Chander Kashyap34076a02012-02-05 23:01:46 +0000185 return fout;
186}
187
Chander Kashyap4131a772011-12-06 23:34:12 +0000188/* exynos4: return ARM clock frequency */
189static unsigned long exynos4_get_arm_clk(void)
Minkyu Kangb1b24682011-01-24 15:22:23 +0900190{
Chander Kashyap4131a772011-12-06 23:34:12 +0000191 struct exynos4_clock *clk =
192 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kangb1b24682011-01-24 15:22:23 +0900193 unsigned long div;
Chander Kashyap3c7721f2011-12-18 22:56:44 +0000194 unsigned long armclk;
195 unsigned int core_ratio;
196 unsigned int core2_ratio;
Minkyu Kangb1b24682011-01-24 15:22:23 +0900197
198 div = readl(&clk->div_cpu0);
199
Chander Kashyap3c7721f2011-12-18 22:56:44 +0000200 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
201 core_ratio = (div >> 0) & 0x7;
202 core2_ratio = (div >> 28) & 0x7;
Minkyu Kangb1b24682011-01-24 15:22:23 +0900203
Chander Kashyap3c7721f2011-12-18 22:56:44 +0000204 armclk = get_pll_clk(APLL) / (core_ratio + 1);
205 armclk /= (core2_ratio + 1);
Minkyu Kangb1b24682011-01-24 15:22:23 +0900206
Chander Kashyap3c7721f2011-12-18 22:56:44 +0000207 return armclk;
Minkyu Kangb1b24682011-01-24 15:22:23 +0900208}
209
Chander Kashyap34076a02012-02-05 23:01:46 +0000210/* exynos5: return ARM clock frequency */
211static 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
Chander Kashyap4131a772011-12-06 23:34:12 +0000232/* exynos4: return pwm clock frequency */
233static unsigned long exynos4_get_pwm_clk(void)
Minkyu Kangb1b24682011-01-24 15:22:23 +0900234{
Chander Kashyap4131a772011-12-06 23:34:12 +0000235 struct exynos4_clock *clk =
236 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kangb1b24682011-01-24 15:22:23 +0900237 unsigned long pclk, sclk;
238 unsigned int sel;
239 unsigned int ratio;
240
Minkyu Kang69b28242011-05-18 16:57:55 +0900241 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;
Minkyu Kangb1b24682011-01-24 15:22:23 +0900248
Minkyu Kang69b28242011-05-18 16:57:55 +0900249 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) {
Minkyu Kangb1b24682011-01-24 15:22:23 +0900265 sclk = get_pll_clk(MPLL);
Minkyu Kang69b28242011-05-18 16:57:55 +0900266 ratio = 8;
267 } else
Minkyu Kangb1b24682011-01-24 15:22:23 +0900268 return 0;
269
Minkyu Kangb1b24682011-01-24 15:22:23 +0900270 pclk = sclk / (ratio + 1);
271
272 return pclk;
273}
274
Chander Kashyap34076a02012-02-05 23:01:46 +0000275/* exynos5: return pwm clock frequency */
276static 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
Chander Kashyap4131a772011-12-06 23:34:12 +0000296/* exynos4: return uart clock frequency */
297static unsigned long exynos4_get_uart_clk(int dev_index)
Minkyu Kangb1b24682011-01-24 15:22:23 +0900298{
Chander Kashyap4131a772011-12-06 23:34:12 +0000299 struct exynos4_clock *clk =
300 (struct exynos4_clock *)samsung_get_base_clock();
Minkyu Kangb1b24682011-01-24 15:22:23 +0900301 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
Chander Kashyap34076a02012-02-05 23:01:46 +0000343/* exynos5: return uart clock frequency */
344static 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
Chander Kashyap4131a772011-12-06 23:34:12 +0000390/* exynos4: set the mmc clock */
391static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
Jaehoon Chung9a772212011-05-17 21:19:17 +0000392{
Chander Kashyap4131a772011-12-06 23:34:12 +0000393 struct exynos4_clock *clk =
394 (struct exynos4_clock *)samsung_get_base_clock();
Jaehoon Chung9a772212011-05-17 21:19:17 +0000395 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
Chander Kashyap34076a02012-02-05 23:01:46 +0000417/* exynos5: set the mmc clock */
418static 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
Donghwa Lee77ba1912012-04-05 19:36:12 +0000444/* get_lcd_clk: return lcd clock frequency */
445static 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
Donghwa Lee3c9d4532012-07-02 01:15:49 +0000486/* get_lcd_clk: return lcd clock frequency */
487static 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
Donghwa Lee77ba1912012-04-05 19:36:12 +0000528void 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
Donghwa Lee3c9d4532012-07-02 01:15:49 +0000590void 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
Donghwa Lee77ba1912012-04-05 19:36:12 +0000652void 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
Rajeshwari Shinde1c9412a2012-07-23 21:23:48 +0000712/*
713 * I2C
714 *
715 * exynos5: obtaining the I2C clock
716 */
717static 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
Minkyu Kangb1b24682011-01-24 15:22:23 +0900735unsigned long get_pll_clk(int pllreg)
736{
Chander Kashyap34076a02012-02-05 23:01:46 +0000737 if (cpu_is_exynos5())
738 return exynos5_get_pll_clk(pllreg);
739 else
740 return exynos4_get_pll_clk(pllreg);
Minkyu Kangb1b24682011-01-24 15:22:23 +0900741}
742
743unsigned long get_arm_clk(void)
744{
Chander Kashyap34076a02012-02-05 23:01:46 +0000745 if (cpu_is_exynos5())
746 return exynos5_get_arm_clk();
747 else
748 return exynos4_get_arm_clk();
Minkyu Kangb1b24682011-01-24 15:22:23 +0900749}
750
Rajeshwari Shinde1c9412a2012-07-23 21:23:48 +0000751unsigned 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
Minkyu Kangb1b24682011-01-24 15:22:23 +0900761unsigned long get_pwm_clk(void)
762{
Chander Kashyap34076a02012-02-05 23:01:46 +0000763 if (cpu_is_exynos5())
764 return exynos5_get_pwm_clk();
765 else
766 return exynos4_get_pwm_clk();
Minkyu Kangb1b24682011-01-24 15:22:23 +0900767}
768
769unsigned long get_uart_clk(int dev_index)
770{
Chander Kashyap34076a02012-02-05 23:01:46 +0000771 if (cpu_is_exynos5())
772 return exynos5_get_uart_clk(dev_index);
773 else
774 return exynos4_get_uart_clk(dev_index);
Minkyu Kangb1b24682011-01-24 15:22:23 +0900775}
Jaehoon Chung9a772212011-05-17 21:19:17 +0000776
777void set_mmc_clk(int dev_index, unsigned int div)
778{
Chander Kashyap34076a02012-02-05 23:01:46 +0000779 if (cpu_is_exynos5())
780 exynos5_set_mmc_clk(dev_index, div);
781 else
782 exynos4_set_mmc_clk(dev_index, div);
Jaehoon Chung9a772212011-05-17 21:19:17 +0000783}
Donghwa Lee77ba1912012-04-05 19:36:12 +0000784
785unsigned long get_lcd_clk(void)
786{
787 if (cpu_is_exynos4())
788 return exynos4_get_lcd_clk();
789 else
Donghwa Lee3c9d4532012-07-02 01:15:49 +0000790 return exynos5_get_lcd_clk();
Donghwa Lee77ba1912012-04-05 19:36:12 +0000791}
792
793void set_lcd_clk(void)
794{
795 if (cpu_is_exynos4())
796 exynos4_set_lcd_clk();
Donghwa Lee3c9d4532012-07-02 01:15:49 +0000797 else
798 exynos5_set_lcd_clk();
Donghwa Lee77ba1912012-04-05 19:36:12 +0000799}
800
801void set_mipi_clk(void)
802{
803 if (cpu_is_exynos4())
804 exynos4_set_mipi_clk();
805}