2 * Copyright (C) 2010 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/arch/clock.h>
11 #include <asm/arch/clk.h>
12 #include <asm/arch/periph.h>
14 #define PLL_DIV_1024 1024
15 #define PLL_DIV_65535 65535
16 #define PLL_DIV_65536 65536
18 * This structure is to store the src bit, div bit and prediv bit
19 * positions of the peripheral clocks of the src and div registers
31 static struct clk_bit_info exynos5_bit_info[] = {
32 /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */
33 {PERIPH_ID_UART0, 0xf, 0xf, -1, 0, 0, -1},
34 {PERIPH_ID_UART1, 0xf, 0xf, -1, 4, 4, -1},
35 {PERIPH_ID_UART2, 0xf, 0xf, -1, 8, 8, -1},
36 {PERIPH_ID_UART3, 0xf, 0xf, -1, 12, 12, -1},
37 {PERIPH_ID_I2C0, -1, 0x7, 0x7, -1, 24, 0},
38 {PERIPH_ID_I2C1, -1, 0x7, 0x7, -1, 24, 0},
39 {PERIPH_ID_I2C2, -1, 0x7, 0x7, -1, 24, 0},
40 {PERIPH_ID_I2C3, -1, 0x7, 0x7, -1, 24, 0},
41 {PERIPH_ID_I2C4, -1, 0x7, 0x7, -1, 24, 0},
42 {PERIPH_ID_I2C5, -1, 0x7, 0x7, -1, 24, 0},
43 {PERIPH_ID_I2C6, -1, 0x7, 0x7, -1, 24, 0},
44 {PERIPH_ID_I2C7, -1, 0x7, 0x7, -1, 24, 0},
45 {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 16, 0, 8},
46 {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 20, 16, 24},
47 {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 24, 0, 8},
48 {PERIPH_ID_SDMMC0, 0xf, 0xf, 0xff, 0, 0, 8},
49 {PERIPH_ID_SDMMC1, 0xf, 0xf, 0xff, 4, 16, 24},
50 {PERIPH_ID_SDMMC2, 0xf, 0xf, 0xff, 8, 0, 8},
51 {PERIPH_ID_SDMMC3, 0xf, 0xf, 0xff, 12, 16, 24},
52 {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4},
53 {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16},
54 {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 0, 0, 4},
55 {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 4, 12, 16},
56 {PERIPH_ID_SDMMC4, 0xf, 0xf, 0xff, 16, 0, 8},
57 {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 0, -1},
58 {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 0, -1},
59 {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 0, -1},
60 {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 0, -1},
61 {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 0, -1},
63 {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1},
66 static struct clk_bit_info exynos542x_bit_info[] = {
67 /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */
68 {PERIPH_ID_UART0, 0xf, 0xf, -1, 4, 8, -1},
69 {PERIPH_ID_UART1, 0xf, 0xf, -1, 8, 12, -1},
70 {PERIPH_ID_UART2, 0xf, 0xf, -1, 12, 16, -1},
71 {PERIPH_ID_UART3, 0xf, 0xf, -1, 16, 20, -1},
72 {PERIPH_ID_I2C0, -1, 0x3f, -1, -1, 8, -1},
73 {PERIPH_ID_I2C1, -1, 0x3f, -1, -1, 8, -1},
74 {PERIPH_ID_I2C2, -1, 0x3f, -1, -1, 8, -1},
75 {PERIPH_ID_I2C3, -1, 0x3f, -1, -1, 8, -1},
76 {PERIPH_ID_I2C4, -1, 0x3f, -1, -1, 8, -1},
77 {PERIPH_ID_I2C5, -1, 0x3f, -1, -1, 8, -1},
78 {PERIPH_ID_I2C6, -1, 0x3f, -1, -1, 8, -1},
79 {PERIPH_ID_I2C7, -1, 0x3f, -1, -1, 8, -1},
80 {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 20, 20, 8},
81 {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 24, 24, 16},
82 {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 28, 28, 24},
83 {PERIPH_ID_SDMMC0, 0x7, 0x3ff, -1, 8, 0, -1},
84 {PERIPH_ID_SDMMC1, 0x7, 0x3ff, -1, 12, 10, -1},
85 {PERIPH_ID_SDMMC2, 0x7, 0x3ff, -1, 16, 20, -1},
86 {PERIPH_ID_I2C8, -1, 0x3f, -1, -1, 8, -1},
87 {PERIPH_ID_I2C9, -1, 0x3f, -1, -1, 8, -1},
88 {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4},
89 {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16},
90 {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 12, 16, 0},
91 {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 16, 20, 8},
92 {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 28, -1},
93 {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 28, -1},
94 {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 28, -1},
95 {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 28, -1},
96 {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 28, -1},
97 {PERIPH_ID_I2C10, -1, 0x3f, -1, -1, 8, -1},
99 {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1},
102 /* Epll Clock division values to achive different frequency output */
103 static struct set_epll_con_val exynos5_epll_div[] = {
104 { 192000000, 0, 48, 3, 1, 0 },
105 { 180000000, 0, 45, 3, 1, 0 },
106 { 73728000, 1, 73, 3, 3, 47710 },
107 { 67737600, 1, 90, 4, 3, 20762 },
108 { 49152000, 0, 49, 3, 3, 9961 },
109 { 45158400, 0, 45, 3, 3, 10381 },
110 { 180633600, 0, 45, 3, 1, 10381 }
113 /* exynos: return pll clock frequency */
114 static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
116 unsigned long m, p, s = 0, mask, fout;
120 * APLL_CON: MIDV [25:16]
121 * MPLL_CON: MIDV [25:16]
122 * EPLL_CON: MIDV [24:16]
123 * VPLL_CON: MIDV [24:16]
124 * BPLL_CON: MIDV [25:16]: Exynos5
126 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL ||
132 m = (r >> 16) & mask;
139 freq = CONFIG_SYS_CLK_FREQ;
141 if (pllreg == EPLL || pllreg == RPLL) {
143 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
144 fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
145 } else if (pllreg == VPLL) {
150 * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
153 * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
156 * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
158 if (proid_is_exynos4210())
160 else if (proid_is_exynos4412())
162 else if (proid_is_exynos5250() || proid_is_exynos5420() ||
163 proid_is_exynos5422())
168 fout = (m + k / div) * (freq / (p * (1 << s)));
171 * Exynos4412 / Exynos5250
172 * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
175 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
177 if (proid_is_exynos4210())
178 fout = m * (freq / (p * (1 << (s - 1))));
180 fout = m * (freq / (p * (1 << s)));
185 /* exynos4: return pll clock frequency */
186 static unsigned long exynos4_get_pll_clk(int pllreg)
188 struct exynos4_clock *clk =
189 (struct exynos4_clock *)samsung_get_base_clock();
190 unsigned long r, k = 0;
194 r = readl(&clk->apll_con0);
197 r = readl(&clk->mpll_con0);
200 r = readl(&clk->epll_con0);
201 k = readl(&clk->epll_con1);
204 r = readl(&clk->vpll_con0);
205 k = readl(&clk->vpll_con1);
208 printf("Unsupported PLL (%d)\n", pllreg);
212 return exynos_get_pll_clk(pllreg, r, k);
215 /* exynos4x12: return pll clock frequency */
216 static unsigned long exynos4x12_get_pll_clk(int pllreg)
218 struct exynos4x12_clock *clk =
219 (struct exynos4x12_clock *)samsung_get_base_clock();
220 unsigned long r, k = 0;
224 r = readl(&clk->apll_con0);
227 r = readl(&clk->mpll_con0);
230 r = readl(&clk->epll_con0);
231 k = readl(&clk->epll_con1);
234 r = readl(&clk->vpll_con0);
235 k = readl(&clk->vpll_con1);
238 printf("Unsupported PLL (%d)\n", pllreg);
242 return exynos_get_pll_clk(pllreg, r, k);
245 /* exynos5: return pll clock frequency */
246 static unsigned long exynos5_get_pll_clk(int pllreg)
248 struct exynos5_clock *clk =
249 (struct exynos5_clock *)samsung_get_base_clock();
250 unsigned long r, k = 0, fout;
251 unsigned int pll_div2_sel, fout_sel;
255 r = readl(&clk->apll_con0);
258 r = readl(&clk->mpll_con0);
261 r = readl(&clk->epll_con0);
262 k = readl(&clk->epll_con1);
265 r = readl(&clk->vpll_con0);
266 k = readl(&clk->vpll_con1);
269 r = readl(&clk->bpll_con0);
272 printf("Unsupported PLL (%d)\n", pllreg);
276 fout = exynos_get_pll_clk(pllreg, r, k);
278 /* According to the user manual, in EVT1 MPLL and BPLL always gives
279 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
280 if (pllreg == MPLL || pllreg == BPLL) {
281 pll_div2_sel = readl(&clk->pll_div2_sel);
285 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
286 & MPLL_FOUT_SEL_MASK;
289 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
290 & BPLL_FOUT_SEL_MASK;
304 /* exynos542x: return pll clock frequency */
305 static unsigned long exynos542x_get_pll_clk(int pllreg)
307 struct exynos5420_clock *clk =
308 (struct exynos5420_clock *)samsung_get_base_clock();
309 unsigned long r, k = 0;
313 r = readl(&clk->apll_con0);
316 r = readl(&clk->mpll_con0);
319 r = readl(&clk->epll_con0);
320 k = readl(&clk->epll_con1);
323 r = readl(&clk->vpll_con0);
324 k = readl(&clk->vpll_con1);
327 r = readl(&clk->bpll_con0);
330 r = readl(&clk->rpll_con0);
331 k = readl(&clk->rpll_con1);
334 r = readl(&clk->spll_con0);
337 printf("Unsupported PLL (%d)\n", pllreg);
341 return exynos_get_pll_clk(pllreg, r, k);
344 static struct clk_bit_info *get_clk_bit_info(int peripheral)
347 struct clk_bit_info *info;
349 if (proid_is_exynos5420() || proid_is_exynos5422())
350 info = exynos542x_bit_info;
352 info = exynos5_bit_info;
354 for (i = 0; info[i].id != PERIPH_ID_NONE; i++) {
355 if (info[i].id == peripheral)
359 if (info[i].id == PERIPH_ID_NONE)
360 debug("ERROR: Peripheral ID %d not found\n", peripheral);
365 static unsigned long exynos5_get_periph_rate(int peripheral)
367 struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
368 unsigned long sclk = 0;
369 unsigned int src = 0, div = 0, sub_div = 0;
370 struct exynos5_clock *clk =
371 (struct exynos5_clock *)samsung_get_base_clock();
373 switch (peripheral) {
374 case PERIPH_ID_UART0:
375 case PERIPH_ID_UART1:
376 case PERIPH_ID_UART2:
377 case PERIPH_ID_UART3:
378 src = readl(&clk->src_peric0);
379 div = readl(&clk->div_peric0);
386 src = readl(&clk->src_peric0);
387 div = readl(&clk->div_peric3);
390 src = readl(&clk->src_mau);
391 div = sub_div = readl(&clk->div_mau);
394 src = readl(&clk->src_peric1);
395 div = sub_div = readl(&clk->div_peric1);
398 src = readl(&clk->src_peric1);
399 div = sub_div = readl(&clk->div_peric2);
403 src = readl(&clk->sclk_src_isp);
404 div = sub_div = readl(&clk->sclk_div_isp);
406 case PERIPH_ID_SDMMC0:
407 case PERIPH_ID_SDMMC1:
408 src = readl(&clk->src_fsys);
409 div = sub_div = readl(&clk->div_fsys1);
411 case PERIPH_ID_SDMMC2:
412 case PERIPH_ID_SDMMC3:
413 src = readl(&clk->src_fsys);
414 div = sub_div = readl(&clk->div_fsys2);
424 src = EXYNOS_SRC_MPLL;
425 div = readl(&clk->div_top1);
426 sub_div = readl(&clk->div_top0);
429 debug("%s: invalid peripheral %d", __func__, peripheral);
433 if (bit_info->src_bit >= 0)
434 src = (src >> bit_info->src_bit) & bit_info->src_mask;
437 case EXYNOS_SRC_MPLL:
438 sclk = exynos5_get_pll_clk(MPLL);
440 case EXYNOS_SRC_EPLL:
441 sclk = exynos5_get_pll_clk(EPLL);
443 case EXYNOS_SRC_VPLL:
444 sclk = exynos5_get_pll_clk(VPLL);
447 debug("%s: EXYNOS_SRC %d not supported\n", __func__, src);
451 /* Clock divider ratio for this peripheral */
452 if (bit_info->div_bit >= 0)
453 div = (div >> bit_info->div_bit) & bit_info->div_mask;
455 /* Clock pre-divider ratio for this peripheral */
456 if (bit_info->prediv_bit >= 0)
457 sub_div = (sub_div >> bit_info->prediv_bit)
458 & bit_info->prediv_mask;
460 /* Calculate and return required clock rate */
461 return (sclk / (div + 1)) / (sub_div + 1);
464 static unsigned long exynos542x_get_periph_rate(int peripheral)
466 struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
467 unsigned long sclk = 0;
468 unsigned int src = 0, div = 0, sub_div = 0;
469 struct exynos5420_clock *clk =
470 (struct exynos5420_clock *)samsung_get_base_clock();
472 switch (peripheral) {
473 case PERIPH_ID_UART0:
474 case PERIPH_ID_UART1:
475 case PERIPH_ID_UART2:
476 case PERIPH_ID_UART3:
482 src = readl(&clk->src_peric0);
483 div = readl(&clk->div_peric0);
488 src = readl(&clk->src_peric1);
489 div = readl(&clk->div_peric1);
490 sub_div = readl(&clk->div_peric4);
494 src = readl(&clk->src_isp);
495 div = readl(&clk->div_isp1);
496 sub_div = readl(&clk->div_isp1);
498 case PERIPH_ID_SDMMC0:
499 case PERIPH_ID_SDMMC1:
500 case PERIPH_ID_SDMMC2:
501 case PERIPH_ID_SDMMC3:
502 src = readl(&clk->src_fsys);
503 div = readl(&clk->div_fsys1);
515 case PERIPH_ID_I2C10:
516 src = EXYNOS542X_SRC_MPLL;
517 div = readl(&clk->div_top1);
520 debug("%s: invalid peripheral %d", __func__, peripheral);
524 if (bit_info->src_bit >= 0)
525 src = (src >> bit_info->src_bit) & bit_info->src_mask;
528 case EXYNOS542X_SRC_MPLL:
529 sclk = exynos542x_get_pll_clk(MPLL);
531 case EXYNOS542X_SRC_SPLL:
532 sclk = exynos542x_get_pll_clk(SPLL);
534 case EXYNOS542X_SRC_EPLL:
535 sclk = exynos542x_get_pll_clk(EPLL);
537 case EXYNOS542X_SRC_RPLL:
538 sclk = exynos542x_get_pll_clk(RPLL);
541 debug("%s: EXYNOS542X_SRC %d not supported", __func__, src);
545 /* Clock divider ratio for this peripheral */
546 if (bit_info->div_bit >= 0)
547 div = (div >> bit_info->div_bit) & bit_info->div_mask;
549 /* Clock pre-divider ratio for this peripheral */
550 if (bit_info->prediv_bit >= 0)
551 sub_div = (sub_div >> bit_info->prediv_bit)
552 & bit_info->prediv_mask;
554 /* Calculate and return required clock rate */
555 return (sclk / (div + 1)) / (sub_div + 1);
558 unsigned long clock_get_periph_rate(int peripheral)
560 if (cpu_is_exynos5()) {
561 if (proid_is_exynos5420() || proid_is_exynos5422())
562 return exynos542x_get_periph_rate(peripheral);
563 return exynos5_get_periph_rate(peripheral);
569 /* exynos4: return ARM clock frequency */
570 static unsigned long exynos4_get_arm_clk(void)
572 struct exynos4_clock *clk =
573 (struct exynos4_clock *)samsung_get_base_clock();
575 unsigned long armclk;
576 unsigned int core_ratio;
577 unsigned int core2_ratio;
579 div = readl(&clk->div_cpu0);
581 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
582 core_ratio = (div >> 0) & 0x7;
583 core2_ratio = (div >> 28) & 0x7;
585 armclk = get_pll_clk(APLL) / (core_ratio + 1);
586 armclk /= (core2_ratio + 1);
591 /* exynos4x12: return ARM clock frequency */
592 static unsigned long exynos4x12_get_arm_clk(void)
594 struct exynos4x12_clock *clk =
595 (struct exynos4x12_clock *)samsung_get_base_clock();
597 unsigned long armclk;
598 unsigned int core_ratio;
599 unsigned int core2_ratio;
601 div = readl(&clk->div_cpu0);
603 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
604 core_ratio = (div >> 0) & 0x7;
605 core2_ratio = (div >> 28) & 0x7;
607 armclk = get_pll_clk(APLL) / (core_ratio + 1);
608 armclk /= (core2_ratio + 1);
613 /* exynos5: return ARM clock frequency */
614 static unsigned long exynos5_get_arm_clk(void)
616 struct exynos5_clock *clk =
617 (struct exynos5_clock *)samsung_get_base_clock();
619 unsigned long armclk;
620 unsigned int arm_ratio;
621 unsigned int arm2_ratio;
623 div = readl(&clk->div_cpu0);
625 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
626 arm_ratio = (div >> 0) & 0x7;
627 arm2_ratio = (div >> 28) & 0x7;
629 armclk = get_pll_clk(APLL) / (arm_ratio + 1);
630 armclk /= (arm2_ratio + 1);
635 /* exynos4: return pwm clock frequency */
636 static unsigned long exynos4_get_pwm_clk(void)
638 struct exynos4_clock *clk =
639 (struct exynos4_clock *)samsung_get_base_clock();
640 unsigned long pclk, sclk;
644 if (s5p_get_cpu_rev() == 0) {
649 sel = readl(&clk->src_peril0);
650 sel = (sel >> 24) & 0xf;
653 sclk = get_pll_clk(MPLL);
655 sclk = get_pll_clk(EPLL);
657 sclk = get_pll_clk(VPLL);
665 ratio = readl(&clk->div_peril3);
667 } else if (s5p_get_cpu_rev() == 1) {
668 sclk = get_pll_clk(MPLL);
673 pclk = sclk / (ratio + 1);
678 /* exynos4x12: return pwm clock frequency */
679 static unsigned long exynos4x12_get_pwm_clk(void)
681 unsigned long pclk, sclk;
684 sclk = get_pll_clk(MPLL);
687 pclk = sclk / (ratio + 1);
692 /* exynos4: return uart clock frequency */
693 static unsigned long exynos4_get_uart_clk(int dev_index)
695 struct exynos4_clock *clk =
696 (struct exynos4_clock *)samsung_get_base_clock();
697 unsigned long uclk, sclk;
710 sel = readl(&clk->src_peril0);
711 sel = (sel >> (dev_index << 2)) & 0xf;
714 sclk = get_pll_clk(MPLL);
716 sclk = get_pll_clk(EPLL);
718 sclk = get_pll_clk(VPLL);
727 * UART3_RATIO [12:15]
728 * UART4_RATIO [16:19]
729 * UART5_RATIO [23:20]
731 ratio = readl(&clk->div_peril0);
732 ratio = (ratio >> (dev_index << 2)) & 0xf;
734 uclk = sclk / (ratio + 1);
739 /* exynos4x12: return uart clock frequency */
740 static unsigned long exynos4x12_get_uart_clk(int dev_index)
742 struct exynos4x12_clock *clk =
743 (struct exynos4x12_clock *)samsung_get_base_clock();
744 unsigned long uclk, sclk;
756 sel = readl(&clk->src_peril0);
757 sel = (sel >> (dev_index << 2)) & 0xf;
760 sclk = get_pll_clk(MPLL);
762 sclk = get_pll_clk(EPLL);
764 sclk = get_pll_clk(VPLL);
773 * UART3_RATIO [12:15]
774 * UART4_RATIO [16:19]
776 ratio = readl(&clk->div_peril0);
777 ratio = (ratio >> (dev_index << 2)) & 0xf;
779 uclk = sclk / (ratio + 1);
784 static unsigned long exynos4_get_mmc_clk(int dev_index)
786 struct exynos4_clock *clk =
787 (struct exynos4_clock *)samsung_get_base_clock();
788 unsigned long uclk, sclk;
789 unsigned int sel, ratio, pre_ratio;
792 sel = readl(&clk->src_fsys);
793 sel = (sel >> (dev_index << 2)) & 0xf;
796 sclk = get_pll_clk(MPLL);
798 sclk = get_pll_clk(EPLL);
800 sclk = get_pll_clk(VPLL);
807 ratio = readl(&clk->div_fsys1);
808 pre_ratio = readl(&clk->div_fsys1);
812 ratio = readl(&clk->div_fsys2);
813 pre_ratio = readl(&clk->div_fsys2);
816 ratio = readl(&clk->div_fsys3);
817 pre_ratio = readl(&clk->div_fsys3);
823 if (dev_index == 1 || dev_index == 3)
826 ratio = (ratio >> shift) & 0xf;
827 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
828 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
833 /* exynos4: set the mmc clock */
834 static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
836 struct exynos4_clock *clk =
837 (struct exynos4_clock *)samsung_get_base_clock();
838 unsigned int addr, clear_bit, set_bit;
842 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
844 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
849 addr = (unsigned int)&clk->div_fsys1;
850 clear_bit = MASK_PRE_RATIO(dev_index);
851 set_bit = SET_PRE_RATIO(dev_index, div);
852 } else if (dev_index == 4) {
853 addr = (unsigned int)&clk->div_fsys3;
855 /* MMC4 is controlled with the MMC4_RATIO value */
856 clear_bit = MASK_RATIO(dev_index);
857 set_bit = SET_RATIO(dev_index, div);
859 addr = (unsigned int)&clk->div_fsys2;
861 clear_bit = MASK_PRE_RATIO(dev_index);
862 set_bit = SET_PRE_RATIO(dev_index, div);
865 clrsetbits_le32(addr, clear_bit, set_bit);
868 /* exynos5: set the mmc clock */
869 static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
871 struct exynos5_clock *clk =
872 (struct exynos5_clock *)samsung_get_base_clock();
877 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
879 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
882 addr = (unsigned int)&clk->div_fsys1;
884 addr = (unsigned int)&clk->div_fsys2;
888 clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
889 (div & 0xff) << ((dev_index << 4) + 8));
892 /* exynos5: set the mmc clock */
893 static void exynos5420_set_mmc_clk(int dev_index, unsigned int div)
895 struct exynos5420_clock *clk =
896 (struct exynos5420_clock *)samsung_get_base_clock();
906 addr = (unsigned int)&clk->div_fsys1;
907 shift = dev_index * 10;
909 clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift);
912 /* get_lcd_clk: return lcd clock frequency */
913 static unsigned long exynos4_get_lcd_clk(void)
915 struct exynos4_clock *clk =
916 (struct exynos4_clock *)samsung_get_base_clock();
917 unsigned long pclk, sclk;
925 sel = readl(&clk->src_lcd0);
934 sclk = get_pll_clk(MPLL);
936 sclk = get_pll_clk(EPLL);
938 sclk = get_pll_clk(VPLL);
946 ratio = readl(&clk->div_lcd0);
949 pclk = sclk / (ratio + 1);
954 /* get_lcd_clk: return lcd clock frequency */
955 static unsigned long exynos5_get_lcd_clk(void)
957 struct exynos5_clock *clk =
958 (struct exynos5_clock *)samsung_get_base_clock();
959 unsigned long pclk, sclk;
967 sel = readl(&clk->src_disp1_0);
976 sclk = get_pll_clk(MPLL);
978 sclk = get_pll_clk(EPLL);
980 sclk = get_pll_clk(VPLL);
988 ratio = readl(&clk->div_disp1_0);
991 pclk = sclk / (ratio + 1);
996 static unsigned long exynos5420_get_lcd_clk(void)
998 struct exynos5420_clock *clk =
999 (struct exynos5420_clock *)samsung_get_base_clock();
1000 unsigned long pclk, sclk;
1010 sel = readl(&clk->src_disp10);
1014 sclk = get_pll_clk(SPLL);
1016 sclk = get_pll_clk(RPLL);
1022 ratio = readl(&clk->div_disp10);
1023 ratio = ratio & 0xf;
1025 pclk = sclk / (ratio + 1);
1030 static unsigned long exynos5800_get_lcd_clk(void)
1032 struct exynos5420_clock *clk =
1033 (struct exynos5420_clock *)samsung_get_base_clock();
1040 * CLKMUX_FIMD1 [6:4]
1042 sel = (readl(&clk->src_disp10) >> 4) & 0x7;
1046 * Mapping of CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] values into
1047 * PLLs. The first element is a placeholder to bypass the
1050 const int reg_map[] = {0, CPLL, DPLL, MPLL, SPLL, IPLL, EPLL,
1052 sclk = get_pll_clk(reg_map[sel]);
1054 sclk = CONFIG_SYS_CLK_FREQ;
1059 ratio = readl(&clk->div_disp10) & 0xf;
1061 return sclk / (ratio + 1);
1064 void exynos4_set_lcd_clk(void)
1066 struct exynos4_clock *clk =
1067 (struct exynos4_clock *)samsung_get_base_clock();
1079 setbits_le32(&clk->gate_block, 1 << 4);
1085 * MDNIE_PWM0_SEL [8:11]
1087 * set lcd0 src clock 0x6: SCLK_MPLL
1089 clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6);
1099 * Gating all clocks for FIMD0
1101 setbits_le32(&clk->gate_ip_lcd0, 1 << 0);
1106 * MDNIE0_RATIO [7:4]
1107 * MDNIE_PWM0_RATIO [11:8]
1108 * MDNIE_PWM_PRE_RATIO [15:12]
1109 * MIPI0_RATIO [19:16]
1110 * MIPI0_PRE_RATIO [23:20]
1113 clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1);
1116 void exynos5_set_lcd_clk(void)
1118 struct exynos5_clock *clk =
1119 (struct exynos5_clock *)samsung_get_base_clock();
1131 setbits_le32(&clk->gate_block, 1 << 4);
1137 * MDNIE_PWM0_SEL [8:11]
1139 * set lcd0 src clock 0x6: SCLK_MPLL
1141 clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6);
1151 * Gating all clocks for FIMD0
1153 setbits_le32(&clk->gate_ip_disp1, 1 << 0);
1158 * MDNIE0_RATIO [7:4]
1159 * MDNIE_PWM0_RATIO [11:8]
1160 * MDNIE_PWM_PRE_RATIO [15:12]
1161 * MIPI0_RATIO [19:16]
1162 * MIPI0_PRE_RATIO [23:20]
1165 clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0);
1168 void exynos5420_set_lcd_clk(void)
1170 struct exynos5420_clock *clk =
1171 (struct exynos5420_clock *)samsung_get_base_clock();
1180 cfg = readl(&clk->src_disp10);
1183 writel(cfg, &clk->src_disp10);
1189 cfg = readl(&clk->div_disp10);
1192 writel(cfg, &clk->div_disp10);
1195 void exynos5800_set_lcd_clk(void)
1197 struct exynos5420_clock *clk =
1198 (struct exynos5420_clock *)samsung_get_base_clock();
1202 * Use RPLL for pixel clock
1203 * CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4]
1204 * ==================
1207 cfg = readl(&clk->src_disp10) | (0x7 << 4);
1208 writel(cfg, &clk->src_disp10);
1214 clrsetbits_le32(&clk->div_disp10, 0xf << 0, 0x0 << 0);
1217 void exynos4_set_mipi_clk(void)
1219 struct exynos4_clock *clk =
1220 (struct exynos4_clock *)samsung_get_base_clock();
1226 * MDNIE_PWM0_SEL [8:11]
1228 * set mipi0 src clock 0x6: SCLK_MPLL
1230 clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12);
1236 * MDNIE_PWM0_MASK [8]
1238 * set src mask mipi0 0x1: Unmask
1240 setbits_le32(&clk->src_mask_lcd0, 0x1 << 12);
1250 * Gating all clocks for MIPI0
1252 setbits_le32(&clk->gate_ip_lcd0, 1 << 3);
1257 * MDNIE0_RATIO [7:4]
1258 * MDNIE_PWM0_RATIO [11:8]
1259 * MDNIE_PWM_PRE_RATIO [15:12]
1260 * MIPI0_RATIO [19:16]
1261 * MIPI0_PRE_RATIO [23:20]
1264 clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16);
1267 int exynos5_set_epll_clk(unsigned long rate)
1269 unsigned int epll_con, epll_con_k;
1271 unsigned int lockcnt;
1273 struct exynos5_clock *clk =
1274 (struct exynos5_clock *)samsung_get_base_clock();
1276 epll_con = readl(&clk->epll_con0);
1277 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1278 EPLL_CON0_LOCK_DET_EN_SHIFT) |
1279 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1280 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1281 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1283 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1284 if (exynos5_epll_div[i].freq_out == rate)
1288 if (i == ARRAY_SIZE(exynos5_epll_div))
1291 epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1292 epll_con |= exynos5_epll_div[i].en_lock_det <<
1293 EPLL_CON0_LOCK_DET_EN_SHIFT;
1294 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1295 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1296 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1299 * Required period ( in cycles) to genarate a stable clock output.
1300 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1301 * frequency input (as per spec)
1303 lockcnt = 3000 * exynos5_epll_div[i].p_div;
1305 writel(lockcnt, &clk->epll_lock);
1306 writel(epll_con, &clk->epll_con0);
1307 writel(epll_con_k, &clk->epll_con1);
1309 start = get_timer(0);
1311 while (!(readl(&clk->epll_con0) &
1312 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1313 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1314 debug("%s: Timeout waiting for EPLL lock\n", __func__);
1321 int exynos5_set_i2s_clk_source(unsigned int i2s_id)
1323 struct exynos5_clock *clk =
1324 (struct exynos5_clock *)samsung_get_base_clock();
1325 unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
1328 setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
1329 clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
1330 (CLK_SRC_SCLK_EPLL));
1331 setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
1332 } else if (i2s_id == 1) {
1333 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1334 (CLK_SRC_SCLK_EPLL));
1341 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
1342 unsigned int dst_frq,
1343 unsigned int i2s_id)
1345 struct exynos5_clock *clk =
1346 (struct exynos5_clock *)samsung_get_base_clock();
1349 if ((dst_frq == 0) || (src_frq == 0)) {
1350 debug("%s: Invalid requency input for prescaler\n", __func__);
1351 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1355 div = (src_frq / dst_frq);
1357 if (div > AUDIO_0_RATIO_MASK) {
1358 debug("%s: Frequency ratio is out of range\n",
1360 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1363 clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
1364 (div & AUDIO_0_RATIO_MASK));
1365 } else if (i2s_id == 1) {
1366 if (div > AUDIO_1_RATIO_MASK) {
1367 debug("%s: Frequency ratio is out of range\n",
1369 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1372 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1373 (div & AUDIO_1_RATIO_MASK));
1381 * Linearly searches for the most accurate main and fine stage clock scalars
1382 * (divisors) for a specified target frequency and scalar bit sizes by checking
1383 * all multiples of main_scalar_bits values. Will always return scalars up to or
1384 * slower than target.
1386 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
1387 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
1388 * @param input_freq Clock frequency to be scaled in Hz
1389 * @param target_freq Desired clock frequency in Hz
1390 * @param best_fine_scalar Pointer to store the fine stage divisor
1392 * @return best_main_scalar Main scalar for desired frequency or -1 if none
1395 static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1396 unsigned int fine_scalar_bits, unsigned int input_rate,
1397 unsigned int target_rate, unsigned int *best_fine_scalar)
1400 int best_main_scalar = -1;
1401 unsigned int best_error = target_rate;
1402 const unsigned int cap = (1 << fine_scalar_bits) - 1;
1403 const unsigned int loops = 1 << main_scaler_bits;
1405 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1408 assert(best_fine_scalar != NULL);
1409 assert(main_scaler_bits <= fine_scalar_bits);
1411 *best_fine_scalar = 1;
1413 if (input_rate == 0 || target_rate == 0)
1416 if (target_rate >= input_rate)
1419 for (i = 1; i <= loops; i++) {
1420 const unsigned int effective_div =
1421 max(min(input_rate / i / target_rate, cap), 1U);
1422 const unsigned int effective_rate = input_rate / i /
1424 const int error = target_rate - effective_rate;
1426 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1427 effective_rate, error);
1429 if (error >= 0 && error <= best_error) {
1431 best_main_scalar = i;
1432 *best_fine_scalar = effective_div;
1436 return best_main_scalar;
1439 static int exynos5_set_spi_clk(enum periph_id periph_id,
1442 struct exynos5_clock *clk =
1443 (struct exynos5_clock *)samsung_get_base_clock();
1446 unsigned shift, pre_shift;
1447 unsigned mask = 0xff;
1450 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1452 debug("%s: Cannot set clock rate for periph %d",
1453 __func__, periph_id);
1459 switch (periph_id) {
1460 case PERIPH_ID_SPI0:
1461 reg = &clk->div_peric1;
1465 case PERIPH_ID_SPI1:
1466 reg = &clk->div_peric1;
1470 case PERIPH_ID_SPI2:
1471 reg = &clk->div_peric2;
1475 case PERIPH_ID_SPI3:
1476 reg = &clk->sclk_div_isp;
1480 case PERIPH_ID_SPI4:
1481 reg = &clk->sclk_div_isp;
1486 debug("%s: Unsupported peripheral ID %d\n", __func__,
1490 clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1491 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1496 static int exynos5420_set_spi_clk(enum periph_id periph_id,
1499 struct exynos5420_clock *clk =
1500 (struct exynos5420_clock *)samsung_get_base_clock();
1503 unsigned shift, pre_shift;
1504 unsigned div_mask = 0xf, pre_div_mask = 0xff;
1508 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1510 debug("%s: Cannot set clock rate for periph %d",
1511 __func__, periph_id);
1517 switch (periph_id) {
1518 case PERIPH_ID_SPI0:
1519 reg = &clk->div_peric1;
1521 pre_reg = &clk->div_peric4;
1524 case PERIPH_ID_SPI1:
1525 reg = &clk->div_peric1;
1527 pre_reg = &clk->div_peric4;
1530 case PERIPH_ID_SPI2:
1531 reg = &clk->div_peric1;
1533 pre_reg = &clk->div_peric4;
1536 case PERIPH_ID_SPI3:
1537 reg = &clk->div_isp1;
1539 pre_reg = &clk->div_isp1;
1542 case PERIPH_ID_SPI4:
1543 reg = &clk->div_isp1;
1545 pre_reg = &clk->div_isp1;
1549 debug("%s: Unsupported peripheral ID %d\n", __func__,
1554 clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
1555 clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
1556 (fine & pre_div_mask) << pre_shift);
1561 static unsigned long exynos4_get_i2c_clk(void)
1563 struct exynos4_clock *clk =
1564 (struct exynos4_clock *)samsung_get_base_clock();
1565 unsigned long sclk, aclk_100;
1568 sclk = get_pll_clk(APLL);
1570 ratio = (readl(&clk->div_top)) >> 4;
1572 aclk_100 = sclk / (ratio + 1);
1576 unsigned long get_pll_clk(int pllreg)
1578 if (cpu_is_exynos5()) {
1579 if (proid_is_exynos5420() || proid_is_exynos5422())
1580 return exynos542x_get_pll_clk(pllreg);
1581 return exynos5_get_pll_clk(pllreg);
1582 } else if (cpu_is_exynos4()) {
1583 if (proid_is_exynos4412())
1584 return exynos4x12_get_pll_clk(pllreg);
1585 return exynos4_get_pll_clk(pllreg);
1591 unsigned long get_arm_clk(void)
1593 if (cpu_is_exynos5()) {
1594 return exynos5_get_arm_clk();
1595 } else if (cpu_is_exynos4()) {
1596 if (proid_is_exynos4412())
1597 return exynos4x12_get_arm_clk();
1598 return exynos4_get_arm_clk();
1604 unsigned long get_i2c_clk(void)
1606 if (cpu_is_exynos5())
1607 return clock_get_periph_rate(PERIPH_ID_I2C0);
1608 else if (cpu_is_exynos4())
1609 return exynos4_get_i2c_clk();
1614 unsigned long get_pwm_clk(void)
1616 if (cpu_is_exynos5()) {
1617 return clock_get_periph_rate(PERIPH_ID_PWM0);
1618 } else if (cpu_is_exynos4()) {
1619 if (proid_is_exynos4412())
1620 return exynos4x12_get_pwm_clk();
1621 return exynos4_get_pwm_clk();
1627 unsigned long get_uart_clk(int dev_index)
1631 switch (dev_index) {
1633 id = PERIPH_ID_UART0;
1636 id = PERIPH_ID_UART1;
1639 id = PERIPH_ID_UART2;
1642 id = PERIPH_ID_UART3;
1645 debug("%s: invalid UART index %d", __func__, dev_index);
1649 if (cpu_is_exynos5()) {
1650 return clock_get_periph_rate(id);
1651 } else if (cpu_is_exynos4()) {
1652 if (proid_is_exynos4412())
1653 return exynos4x12_get_uart_clk(dev_index);
1654 return exynos4_get_uart_clk(dev_index);
1660 unsigned long get_mmc_clk(int dev_index)
1664 if (cpu_is_exynos4())
1665 return exynos4_get_mmc_clk(dev_index);
1667 switch (dev_index) {
1669 id = PERIPH_ID_SDMMC0;
1672 id = PERIPH_ID_SDMMC1;
1675 id = PERIPH_ID_SDMMC2;
1678 id = PERIPH_ID_SDMMC3;
1681 debug("%s: invalid MMC index %d", __func__, dev_index);
1685 return clock_get_periph_rate(id);
1688 void set_mmc_clk(int dev_index, unsigned int div)
1690 /* If want to set correct value, it needs to substract one from div.*/
1694 if (cpu_is_exynos5()) {
1695 if (proid_is_exynos5420() || proid_is_exynos5422())
1696 exynos5420_set_mmc_clk(dev_index, div);
1698 exynos5_set_mmc_clk(dev_index, div);
1699 } else if (cpu_is_exynos4()) {
1700 exynos4_set_mmc_clk(dev_index, div);
1704 unsigned long get_lcd_clk(void)
1706 if (cpu_is_exynos4()) {
1707 return exynos4_get_lcd_clk();
1708 } else if (cpu_is_exynos5()) {
1709 if (proid_is_exynos5420())
1710 return exynos5420_get_lcd_clk();
1711 else if (proid_is_exynos5422())
1712 return exynos5800_get_lcd_clk();
1714 return exynos5_get_lcd_clk();
1720 void set_lcd_clk(void)
1722 if (cpu_is_exynos4()) {
1723 exynos4_set_lcd_clk();
1724 } else if (cpu_is_exynos5()) {
1725 if (proid_is_exynos5250())
1726 exynos5_set_lcd_clk();
1727 else if (proid_is_exynos5420())
1728 exynos5420_set_lcd_clk();
1730 exynos5800_set_lcd_clk();
1734 void set_mipi_clk(void)
1736 if (cpu_is_exynos4())
1737 exynos4_set_mipi_clk();
1740 int set_spi_clk(int periph_id, unsigned int rate)
1742 if (cpu_is_exynos5()) {
1743 if (proid_is_exynos5420() || proid_is_exynos5422())
1744 return exynos5420_set_spi_clk(periph_id, rate);
1745 return exynos5_set_spi_clk(periph_id, rate);
1751 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
1752 unsigned int i2s_id)
1754 if (cpu_is_exynos5())
1755 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
1760 int set_i2s_clk_source(unsigned int i2s_id)
1762 if (cpu_is_exynos5())
1763 return exynos5_set_i2s_clk_source(i2s_id);
1768 int set_epll_clk(unsigned long rate)
1770 if (cpu_is_exynos5())
1771 return exynos5_set_epll_clk(rate);