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
19 * This structure is to store the src bit, div bit and prediv bit
20 * positions of the peripheral clocks of the src and div registers
28 /* src_bit div_bit prediv_bit */
29 static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
61 /* Epll Clock division values to achive different frequency output */
62 static struct set_epll_con_val exynos5_epll_div[] = {
63 { 192000000, 0, 48, 3, 1, 0 },
64 { 180000000, 0, 45, 3, 1, 0 },
65 { 73728000, 1, 73, 3, 3, 47710 },
66 { 67737600, 1, 90, 4, 3, 20762 },
67 { 49152000, 0, 49, 3, 3, 9961 },
68 { 45158400, 0, 45, 3, 3, 10381 },
69 { 180633600, 0, 45, 3, 1, 10381 }
72 /* exynos: return pll clock frequency */
73 static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
75 unsigned long m, p, s = 0, mask, fout;
79 * APLL_CON: MIDV [25:16]
80 * MPLL_CON: MIDV [25:16]
81 * EPLL_CON: MIDV [24:16]
82 * VPLL_CON: MIDV [24:16]
83 * BPLL_CON: MIDV [25:16]: Exynos5
85 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL)
97 freq = CONFIG_SYS_CLK_FREQ;
101 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
102 fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
103 } else if (pllreg == VPLL) {
108 * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
111 * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
114 * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
116 if (proid_is_exynos4210())
118 else if (proid_is_exynos4412())
120 else if (proid_is_exynos5250())
125 fout = (m + k / div) * (freq / (p * (1 << s)));
128 * Exynos4412 / Exynos5250
129 * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
132 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
134 if (proid_is_exynos4210())
135 fout = m * (freq / (p * (1 << (s - 1))));
137 fout = m * (freq / (p * (1 << s)));
142 /* exynos4: return pll clock frequency */
143 static unsigned long exynos4_get_pll_clk(int pllreg)
145 struct exynos4_clock *clk =
146 (struct exynos4_clock *)samsung_get_base_clock();
147 unsigned long r, k = 0;
151 r = readl(&clk->apll_con0);
154 r = readl(&clk->mpll_con0);
157 r = readl(&clk->epll_con0);
158 k = readl(&clk->epll_con1);
161 r = readl(&clk->vpll_con0);
162 k = readl(&clk->vpll_con1);
165 printf("Unsupported PLL (%d)\n", pllreg);
169 return exynos_get_pll_clk(pllreg, r, k);
172 /* exynos4x12: return pll clock frequency */
173 static unsigned long exynos4x12_get_pll_clk(int pllreg)
175 struct exynos4x12_clock *clk =
176 (struct exynos4x12_clock *)samsung_get_base_clock();
177 unsigned long r, k = 0;
181 r = readl(&clk->apll_con0);
184 r = readl(&clk->mpll_con0);
187 r = readl(&clk->epll_con0);
188 k = readl(&clk->epll_con1);
191 r = readl(&clk->vpll_con0);
192 k = readl(&clk->vpll_con1);
195 printf("Unsupported PLL (%d)\n", pllreg);
199 return exynos_get_pll_clk(pllreg, r, k);
202 /* exynos5: return pll clock frequency */
203 static unsigned long exynos5_get_pll_clk(int pllreg)
205 struct exynos5_clock *clk =
206 (struct exynos5_clock *)samsung_get_base_clock();
207 unsigned long r, k = 0, fout;
208 unsigned int pll_div2_sel, fout_sel;
212 r = readl(&clk->apll_con0);
215 r = readl(&clk->mpll_con0);
218 r = readl(&clk->epll_con0);
219 k = readl(&clk->epll_con1);
222 r = readl(&clk->vpll_con0);
223 k = readl(&clk->vpll_con1);
226 r = readl(&clk->bpll_con0);
229 printf("Unsupported PLL (%d)\n", pllreg);
233 fout = exynos_get_pll_clk(pllreg, r, k);
235 /* According to the user manual, in EVT1 MPLL and BPLL always gives
236 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
237 if (pllreg == MPLL || pllreg == BPLL) {
238 pll_div2_sel = readl(&clk->pll_div2_sel);
242 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
243 & MPLL_FOUT_SEL_MASK;
246 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
247 & BPLL_FOUT_SEL_MASK;
261 static unsigned long exynos5_get_periph_rate(int peripheral)
263 struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
264 unsigned long sclk, sub_clk;
265 unsigned int src, div, sub_div;
266 struct exynos5_clock *clk =
267 (struct exynos5_clock *)samsung_get_base_clock();
269 switch (peripheral) {
270 case PERIPH_ID_UART0:
271 case PERIPH_ID_UART1:
272 case PERIPH_ID_UART2:
273 case PERIPH_ID_UART3:
274 src = readl(&clk->src_peric0);
275 div = readl(&clk->div_peric0);
282 src = readl(&clk->src_peric0);
283 div = readl(&clk->div_peric3);
286 src = readl(&clk->src_mau);
287 div = readl(&clk->div_mau);
290 src = readl(&clk->src_peric1);
291 div = readl(&clk->div_peric1);
294 src = readl(&clk->src_peric1);
295 div = readl(&clk->div_peric2);
299 src = readl(&clk->sclk_src_isp);
300 div = readl(&clk->sclk_div_isp);
302 case PERIPH_ID_SDMMC0:
303 case PERIPH_ID_SDMMC1:
304 case PERIPH_ID_SDMMC2:
305 case PERIPH_ID_SDMMC3:
306 src = readl(&clk->src_fsys);
307 div = readl(&clk->div_fsys1);
317 sclk = exynos5_get_pll_clk(MPLL);
318 sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit)
320 div = ((readl(&clk->div_top0) >> bit_info->prediv_bit)
322 return (sclk / sub_div) / div;
324 debug("%s: invalid peripheral %d", __func__, peripheral);
328 src = (src >> bit_info->src_bit) & 0xf;
331 case EXYNOS_SRC_MPLL:
332 sclk = exynos5_get_pll_clk(MPLL);
334 case EXYNOS_SRC_EPLL:
335 sclk = exynos5_get_pll_clk(EPLL);
337 case EXYNOS_SRC_VPLL:
338 sclk = exynos5_get_pll_clk(VPLL);
344 /* Ratio clock division for this peripheral */
345 sub_div = (div >> bit_info->div_bit) & 0xf;
346 sub_clk = sclk / (sub_div + 1);
348 /* Pre-ratio clock division for SDMMC0 and 2 */
349 if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
350 div = (div >> bit_info->prediv_bit) & 0xff;
351 return sub_clk / (div + 1);
357 unsigned long clock_get_periph_rate(int peripheral)
359 if (cpu_is_exynos5())
360 return exynos5_get_periph_rate(peripheral);
365 /* exynos4: return ARM clock frequency */
366 static unsigned long exynos4_get_arm_clk(void)
368 struct exynos4_clock *clk =
369 (struct exynos4_clock *)samsung_get_base_clock();
371 unsigned long armclk;
372 unsigned int core_ratio;
373 unsigned int core2_ratio;
375 div = readl(&clk->div_cpu0);
377 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
378 core_ratio = (div >> 0) & 0x7;
379 core2_ratio = (div >> 28) & 0x7;
381 armclk = get_pll_clk(APLL) / (core_ratio + 1);
382 armclk /= (core2_ratio + 1);
387 /* exynos4x12: return ARM clock frequency */
388 static unsigned long exynos4x12_get_arm_clk(void)
390 struct exynos4x12_clock *clk =
391 (struct exynos4x12_clock *)samsung_get_base_clock();
393 unsigned long armclk;
394 unsigned int core_ratio;
395 unsigned int core2_ratio;
397 div = readl(&clk->div_cpu0);
399 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
400 core_ratio = (div >> 0) & 0x7;
401 core2_ratio = (div >> 28) & 0x7;
403 armclk = get_pll_clk(APLL) / (core_ratio + 1);
404 armclk /= (core2_ratio + 1);
409 /* exynos5: return ARM clock frequency */
410 static unsigned long exynos5_get_arm_clk(void)
412 struct exynos5_clock *clk =
413 (struct exynos5_clock *)samsung_get_base_clock();
415 unsigned long armclk;
416 unsigned int arm_ratio;
417 unsigned int arm2_ratio;
419 div = readl(&clk->div_cpu0);
421 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
422 arm_ratio = (div >> 0) & 0x7;
423 arm2_ratio = (div >> 28) & 0x7;
425 armclk = get_pll_clk(APLL) / (arm_ratio + 1);
426 armclk /= (arm2_ratio + 1);
431 /* exynos4: return pwm clock frequency */
432 static unsigned long exynos4_get_pwm_clk(void)
434 struct exynos4_clock *clk =
435 (struct exynos4_clock *)samsung_get_base_clock();
436 unsigned long pclk, sclk;
440 if (s5p_get_cpu_rev() == 0) {
445 sel = readl(&clk->src_peril0);
446 sel = (sel >> 24) & 0xf;
449 sclk = get_pll_clk(MPLL);
451 sclk = get_pll_clk(EPLL);
453 sclk = get_pll_clk(VPLL);
461 ratio = readl(&clk->div_peril3);
463 } else if (s5p_get_cpu_rev() == 1) {
464 sclk = get_pll_clk(MPLL);
469 pclk = sclk / (ratio + 1);
474 /* exynos4x12: return pwm clock frequency */
475 static unsigned long exynos4x12_get_pwm_clk(void)
477 unsigned long pclk, sclk;
480 sclk = get_pll_clk(MPLL);
483 pclk = sclk / (ratio + 1);
488 /* exynos4: return uart clock frequency */
489 static unsigned long exynos4_get_uart_clk(int dev_index)
491 struct exynos4_clock *clk =
492 (struct exynos4_clock *)samsung_get_base_clock();
493 unsigned long uclk, sclk;
506 sel = readl(&clk->src_peril0);
507 sel = (sel >> (dev_index << 2)) & 0xf;
510 sclk = get_pll_clk(MPLL);
512 sclk = get_pll_clk(EPLL);
514 sclk = get_pll_clk(VPLL);
523 * UART3_RATIO [12:15]
524 * UART4_RATIO [16:19]
525 * UART5_RATIO [23:20]
527 ratio = readl(&clk->div_peril0);
528 ratio = (ratio >> (dev_index << 2)) & 0xf;
530 uclk = sclk / (ratio + 1);
535 /* exynos4x12: return uart clock frequency */
536 static unsigned long exynos4x12_get_uart_clk(int dev_index)
538 struct exynos4x12_clock *clk =
539 (struct exynos4x12_clock *)samsung_get_base_clock();
540 unsigned long uclk, sclk;
552 sel = readl(&clk->src_peril0);
553 sel = (sel >> (dev_index << 2)) & 0xf;
556 sclk = get_pll_clk(MPLL);
558 sclk = get_pll_clk(EPLL);
560 sclk = get_pll_clk(VPLL);
569 * UART3_RATIO [12:15]
570 * UART4_RATIO [16:19]
572 ratio = readl(&clk->div_peril0);
573 ratio = (ratio >> (dev_index << 2)) & 0xf;
575 uclk = sclk / (ratio + 1);
580 /* exynos5: return uart clock frequency */
581 static unsigned long exynos5_get_uart_clk(int dev_index)
583 struct exynos5_clock *clk =
584 (struct exynos5_clock *)samsung_get_base_clock();
585 unsigned long uclk, sclk;
598 sel = readl(&clk->src_peric0);
599 sel = (sel >> (dev_index << 2)) & 0xf;
602 sclk = get_pll_clk(MPLL);
604 sclk = get_pll_clk(EPLL);
606 sclk = get_pll_clk(VPLL);
615 * UART3_RATIO [12:15]
616 * UART4_RATIO [16:19]
617 * UART5_RATIO [23:20]
619 ratio = readl(&clk->div_peric0);
620 ratio = (ratio >> (dev_index << 2)) & 0xf;
622 uclk = sclk / (ratio + 1);
627 static unsigned long exynos4_get_mmc_clk(int dev_index)
629 struct exynos4_clock *clk =
630 (struct exynos4_clock *)samsung_get_base_clock();
631 unsigned long uclk, sclk;
632 unsigned int sel, ratio, pre_ratio;
635 sel = readl(&clk->src_fsys);
636 sel = (sel >> (dev_index << 2)) & 0xf;
639 sclk = get_pll_clk(MPLL);
641 sclk = get_pll_clk(EPLL);
643 sclk = get_pll_clk(VPLL);
650 ratio = readl(&clk->div_fsys1);
651 pre_ratio = readl(&clk->div_fsys1);
655 ratio = readl(&clk->div_fsys2);
656 pre_ratio = readl(&clk->div_fsys2);
659 ratio = readl(&clk->div_fsys3);
660 pre_ratio = readl(&clk->div_fsys3);
666 if (dev_index == 1 || dev_index == 3)
669 ratio = (ratio >> shift) & 0xf;
670 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
671 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
676 static unsigned long exynos5_get_mmc_clk(int dev_index)
678 struct exynos5_clock *clk =
679 (struct exynos5_clock *)samsung_get_base_clock();
680 unsigned long uclk, sclk;
681 unsigned int sel, ratio, pre_ratio;
684 sel = readl(&clk->src_fsys);
685 sel = (sel >> (dev_index << 2)) & 0xf;
688 sclk = get_pll_clk(MPLL);
690 sclk = get_pll_clk(EPLL);
692 sclk = get_pll_clk(VPLL);
699 ratio = readl(&clk->div_fsys1);
700 pre_ratio = readl(&clk->div_fsys1);
704 ratio = readl(&clk->div_fsys2);
705 pre_ratio = readl(&clk->div_fsys2);
711 if (dev_index == 1 || dev_index == 3)
714 ratio = (ratio >> shift) & 0xf;
715 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
716 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
721 /* exynos4: set the mmc clock */
722 static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
724 struct exynos4_clock *clk =
725 (struct exynos4_clock *)samsung_get_base_clock();
731 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
733 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
735 * MMC4_PRE_RATIO [15:8]
738 addr = (unsigned int)&clk->div_fsys1;
739 } else if (dev_index == 4) {
740 addr = (unsigned int)&clk->div_fsys3;
743 addr = (unsigned int)&clk->div_fsys2;
748 val &= ~(0xff << ((dev_index << 4) + 8));
749 val |= (div & 0xff) << ((dev_index << 4) + 8);
753 /* exynos4x12: set the mmc clock */
754 static void exynos4x12_set_mmc_clk(int dev_index, unsigned int div)
756 struct exynos4x12_clock *clk =
757 (struct exynos4x12_clock *)samsung_get_base_clock();
763 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
765 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
768 addr = (unsigned int)&clk->div_fsys1;
770 addr = (unsigned int)&clk->div_fsys2;
775 val &= ~(0xff << ((dev_index << 4) + 8));
776 val |= (div & 0xff) << ((dev_index << 4) + 8);
780 /* exynos5: set the mmc clock */
781 static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
783 struct exynos5_clock *clk =
784 (struct exynos5_clock *)samsung_get_base_clock();
790 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
792 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
795 addr = (unsigned int)&clk->div_fsys1;
797 addr = (unsigned int)&clk->div_fsys2;
802 val &= ~(0xff << ((dev_index << 4) + 8));
803 val |= (div & 0xff) << ((dev_index << 4) + 8);
807 /* get_lcd_clk: return lcd clock frequency */
808 static unsigned long exynos4_get_lcd_clk(void)
810 struct exynos4_clock *clk =
811 (struct exynos4_clock *)samsung_get_base_clock();
812 unsigned long pclk, sclk;
820 sel = readl(&clk->src_lcd0);
829 sclk = get_pll_clk(MPLL);
831 sclk = get_pll_clk(EPLL);
833 sclk = get_pll_clk(VPLL);
841 ratio = readl(&clk->div_lcd0);
844 pclk = sclk / (ratio + 1);
849 /* get_lcd_clk: return lcd clock frequency */
850 static unsigned long exynos5_get_lcd_clk(void)
852 struct exynos5_clock *clk =
853 (struct exynos5_clock *)samsung_get_base_clock();
854 unsigned long pclk, sclk;
862 sel = readl(&clk->src_disp1_0);
871 sclk = get_pll_clk(MPLL);
873 sclk = get_pll_clk(EPLL);
875 sclk = get_pll_clk(VPLL);
883 ratio = readl(&clk->div_disp1_0);
886 pclk = sclk / (ratio + 1);
891 void exynos4_set_lcd_clk(void)
893 struct exynos4_clock *clk =
894 (struct exynos4_clock *)samsung_get_base_clock();
895 unsigned int cfg = 0;
907 cfg = readl(&clk->gate_block);
909 writel(cfg, &clk->gate_block);
915 * MDNIE_PWM0_SEL [8:11]
917 * set lcd0 src clock 0x6: SCLK_MPLL
919 cfg = readl(&clk->src_lcd0);
922 writel(cfg, &clk->src_lcd0);
932 * Gating all clocks for FIMD0
934 cfg = readl(&clk->gate_ip_lcd0);
936 writel(cfg, &clk->gate_ip_lcd0);
942 * MDNIE_PWM0_RATIO [11:8]
943 * MDNIE_PWM_PRE_RATIO [15:12]
944 * MIPI0_RATIO [19:16]
945 * MIPI0_PRE_RATIO [23:20]
950 writel(cfg, &clk->div_lcd0);
953 void exynos5_set_lcd_clk(void)
955 struct exynos5_clock *clk =
956 (struct exynos5_clock *)samsung_get_base_clock();
957 unsigned int cfg = 0;
969 cfg = readl(&clk->gate_block);
971 writel(cfg, &clk->gate_block);
977 * MDNIE_PWM0_SEL [8:11]
979 * set lcd0 src clock 0x6: SCLK_MPLL
981 cfg = readl(&clk->src_disp1_0);
984 writel(cfg, &clk->src_disp1_0);
994 * Gating all clocks for FIMD0
996 cfg = readl(&clk->gate_ip_disp1);
998 writel(cfg, &clk->gate_ip_disp1);
1003 * MDNIE0_RATIO [7:4]
1004 * MDNIE_PWM0_RATIO [11:8]
1005 * MDNIE_PWM_PRE_RATIO [15:12]
1006 * MIPI0_RATIO [19:16]
1007 * MIPI0_PRE_RATIO [23:20]
1012 writel(cfg, &clk->div_disp1_0);
1015 void exynos4_set_mipi_clk(void)
1017 struct exynos4_clock *clk =
1018 (struct exynos4_clock *)samsung_get_base_clock();
1019 unsigned int cfg = 0;
1025 * MDNIE_PWM0_SEL [8:11]
1027 * set mipi0 src clock 0x6: SCLK_MPLL
1029 cfg = readl(&clk->src_lcd0);
1030 cfg &= ~(0xf << 12);
1032 writel(cfg, &clk->src_lcd0);
1038 * MDNIE_PWM0_MASK [8]
1040 * set src mask mipi0 0x1: Unmask
1042 cfg = readl(&clk->src_mask_lcd0);
1044 writel(cfg, &clk->src_mask_lcd0);
1054 * Gating all clocks for MIPI0
1056 cfg = readl(&clk->gate_ip_lcd0);
1058 writel(cfg, &clk->gate_ip_lcd0);
1063 * MDNIE0_RATIO [7:4]
1064 * MDNIE_PWM0_RATIO [11:8]
1065 * MDNIE_PWM_PRE_RATIO [15:12]
1066 * MIPI0_RATIO [19:16]
1067 * MIPI0_PRE_RATIO [23:20]
1070 cfg &= ~(0xf << 16);
1072 writel(cfg, &clk->div_lcd0);
1078 * exynos5: obtaining the I2C clock
1080 static unsigned long exynos5_get_i2c_clk(void)
1082 struct exynos5_clock *clk =
1083 (struct exynos5_clock *)samsung_get_base_clock();
1084 unsigned long aclk_66, aclk_66_pre, sclk;
1087 sclk = get_pll_clk(MPLL);
1089 ratio = (readl(&clk->div_top1)) >> 24;
1091 aclk_66_pre = sclk / (ratio + 1);
1092 ratio = readl(&clk->div_top0);
1094 aclk_66 = aclk_66_pre / (ratio + 1);
1098 int exynos5_set_epll_clk(unsigned long rate)
1100 unsigned int epll_con, epll_con_k;
1102 unsigned int lockcnt;
1104 struct exynos5_clock *clk =
1105 (struct exynos5_clock *)samsung_get_base_clock();
1107 epll_con = readl(&clk->epll_con0);
1108 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1109 EPLL_CON0_LOCK_DET_EN_SHIFT) |
1110 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1111 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1112 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1114 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1115 if (exynos5_epll_div[i].freq_out == rate)
1119 if (i == ARRAY_SIZE(exynos5_epll_div))
1122 epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1123 epll_con |= exynos5_epll_div[i].en_lock_det <<
1124 EPLL_CON0_LOCK_DET_EN_SHIFT;
1125 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1126 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1127 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1130 * Required period ( in cycles) to genarate a stable clock output.
1131 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1132 * frequency input (as per spec)
1134 lockcnt = 3000 * exynos5_epll_div[i].p_div;
1136 writel(lockcnt, &clk->epll_lock);
1137 writel(epll_con, &clk->epll_con0);
1138 writel(epll_con_k, &clk->epll_con1);
1140 start = get_timer(0);
1142 while (!(readl(&clk->epll_con0) &
1143 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1144 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1145 debug("%s: Timeout waiting for EPLL lock\n", __func__);
1152 int exynos5_set_i2s_clk_source(unsigned int i2s_id)
1154 struct exynos5_clock *clk =
1155 (struct exynos5_clock *)samsung_get_base_clock();
1156 unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
1159 setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
1160 clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
1161 (CLK_SRC_SCLK_EPLL));
1162 setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
1163 } else if (i2s_id == 1) {
1164 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1165 (CLK_SRC_SCLK_EPLL));
1172 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
1173 unsigned int dst_frq,
1174 unsigned int i2s_id)
1176 struct exynos5_clock *clk =
1177 (struct exynos5_clock *)samsung_get_base_clock();
1180 if ((dst_frq == 0) || (src_frq == 0)) {
1181 debug("%s: Invalid requency input for prescaler\n", __func__);
1182 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1186 div = (src_frq / dst_frq);
1188 if (div > AUDIO_0_RATIO_MASK) {
1189 debug("%s: Frequency ratio is out of range\n",
1191 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1194 clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
1195 (div & AUDIO_0_RATIO_MASK));
1196 } else if(i2s_id == 1) {
1197 if (div > AUDIO_1_RATIO_MASK) {
1198 debug("%s: Frequency ratio is out of range\n",
1200 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1203 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1204 (div & AUDIO_1_RATIO_MASK));
1212 * Linearly searches for the most accurate main and fine stage clock scalars
1213 * (divisors) for a specified target frequency and scalar bit sizes by checking
1214 * all multiples of main_scalar_bits values. Will always return scalars up to or
1215 * slower than target.
1217 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
1218 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
1219 * @param input_freq Clock frequency to be scaled in Hz
1220 * @param target_freq Desired clock frequency in Hz
1221 * @param best_fine_scalar Pointer to store the fine stage divisor
1223 * @return best_main_scalar Main scalar for desired frequency or -1 if none
1226 static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1227 unsigned int fine_scalar_bits, unsigned int input_rate,
1228 unsigned int target_rate, unsigned int *best_fine_scalar)
1231 int best_main_scalar = -1;
1232 unsigned int best_error = target_rate;
1233 const unsigned int cap = (1 << fine_scalar_bits) - 1;
1234 const unsigned int loops = 1 << main_scaler_bits;
1236 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1239 assert(best_fine_scalar != NULL);
1240 assert(main_scaler_bits <= fine_scalar_bits);
1242 *best_fine_scalar = 1;
1244 if (input_rate == 0 || target_rate == 0)
1247 if (target_rate >= input_rate)
1250 for (i = 1; i <= loops; i++) {
1251 const unsigned int effective_div = max(min(input_rate / i /
1252 target_rate, cap), 1);
1253 const unsigned int effective_rate = input_rate / i /
1255 const int error = target_rate - effective_rate;
1257 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1258 effective_rate, error);
1260 if (error >= 0 && error <= best_error) {
1262 best_main_scalar = i;
1263 *best_fine_scalar = effective_div;
1267 return best_main_scalar;
1270 static int exynos5_set_spi_clk(enum periph_id periph_id,
1273 struct exynos5_clock *clk =
1274 (struct exynos5_clock *)samsung_get_base_clock();
1277 unsigned shift, pre_shift;
1278 unsigned mask = 0xff;
1281 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1283 debug("%s: Cannot set clock rate for periph %d",
1284 __func__, periph_id);
1290 switch (periph_id) {
1291 case PERIPH_ID_SPI0:
1292 reg = &clk->div_peric1;
1296 case PERIPH_ID_SPI1:
1297 reg = &clk->div_peric1;
1301 case PERIPH_ID_SPI2:
1302 reg = &clk->div_peric2;
1306 case PERIPH_ID_SPI3:
1307 reg = &clk->sclk_div_isp;
1311 case PERIPH_ID_SPI4:
1312 reg = &clk->sclk_div_isp;
1317 debug("%s: Unsupported peripheral ID %d\n", __func__,
1321 clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1322 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1327 static unsigned long exynos4_get_i2c_clk(void)
1329 struct exynos4_clock *clk =
1330 (struct exynos4_clock *)samsung_get_base_clock();
1331 unsigned long sclk, aclk_100;
1334 sclk = get_pll_clk(APLL);
1336 ratio = (readl(&clk->div_top)) >> 4;
1338 aclk_100 = sclk / (ratio + 1);
1342 unsigned long get_pll_clk(int pllreg)
1344 if (cpu_is_exynos5())
1345 return exynos5_get_pll_clk(pllreg);
1347 if (proid_is_exynos4412())
1348 return exynos4x12_get_pll_clk(pllreg);
1349 return exynos4_get_pll_clk(pllreg);
1353 unsigned long get_arm_clk(void)
1355 if (cpu_is_exynos5())
1356 return exynos5_get_arm_clk();
1358 if (proid_is_exynos4412())
1359 return exynos4x12_get_arm_clk();
1360 return exynos4_get_arm_clk();
1364 unsigned long get_i2c_clk(void)
1366 if (cpu_is_exynos5()) {
1367 return exynos5_get_i2c_clk();
1368 } else if (cpu_is_exynos4()) {
1369 return exynos4_get_i2c_clk();
1371 debug("I2C clock is not set for this CPU\n");
1376 unsigned long get_pwm_clk(void)
1378 if (cpu_is_exynos5())
1379 return clock_get_periph_rate(PERIPH_ID_PWM0);
1381 if (proid_is_exynos4412())
1382 return exynos4x12_get_pwm_clk();
1383 return exynos4_get_pwm_clk();
1387 unsigned long get_uart_clk(int dev_index)
1389 if (cpu_is_exynos5())
1390 return exynos5_get_uart_clk(dev_index);
1392 if (proid_is_exynos4412())
1393 return exynos4x12_get_uart_clk(dev_index);
1394 return exynos4_get_uart_clk(dev_index);
1398 unsigned long get_mmc_clk(int dev_index)
1400 if (cpu_is_exynos5())
1401 return exynos5_get_mmc_clk(dev_index);
1403 return exynos4_get_mmc_clk(dev_index);
1406 void set_mmc_clk(int dev_index, unsigned int div)
1408 if (cpu_is_exynos5())
1409 exynos5_set_mmc_clk(dev_index, div);
1411 if (proid_is_exynos4412())
1412 exynos4x12_set_mmc_clk(dev_index, div);
1413 exynos4_set_mmc_clk(dev_index, div);
1417 unsigned long get_lcd_clk(void)
1419 if (cpu_is_exynos4())
1420 return exynos4_get_lcd_clk();
1422 return exynos5_get_lcd_clk();
1425 void set_lcd_clk(void)
1427 if (cpu_is_exynos4())
1428 exynos4_set_lcd_clk();
1430 exynos5_set_lcd_clk();
1433 void set_mipi_clk(void)
1435 if (cpu_is_exynos4())
1436 exynos4_set_mipi_clk();
1439 int set_spi_clk(int periph_id, unsigned int rate)
1441 if (cpu_is_exynos5())
1442 return exynos5_set_spi_clk(periph_id, rate);
1447 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
1448 unsigned int i2s_id)
1450 if (cpu_is_exynos5())
1451 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
1456 int set_i2s_clk_source(unsigned int i2s_id)
1458 if (cpu_is_exynos5())
1459 return exynos5_set_i2s_clk_source(i2s_id);
1464 int set_epll_clk(unsigned long rate)
1466 if (cpu_is_exynos5())
1467 return exynos5_set_epll_clk(rate);