2 * Copyright (C) 2010 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
26 #include <asm/arch/clock.h>
27 #include <asm/arch/clk.h>
28 #include <asm/arch/periph.h>
30 #define PLL_DIV_1024 1024
31 #define PLL_DIV_65535 65535
32 #define PLL_DIV_65536 65536
35 * This structure is to store the src bit, div bit and prediv bit
36 * positions of the peripheral clocks of the src and div registers
44 /* src_bit div_bit prediv_bit */
45 static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
77 /* Epll Clock division values to achive different frequency output */
78 static struct set_epll_con_val exynos5_epll_div[] = {
79 { 192000000, 0, 48, 3, 1, 0 },
80 { 180000000, 0, 45, 3, 1, 0 },
81 { 73728000, 1, 73, 3, 3, 47710 },
82 { 67737600, 1, 90, 4, 3, 20762 },
83 { 49152000, 0, 49, 3, 3, 9961 },
84 { 45158400, 0, 45, 3, 3, 10381 },
85 { 180633600, 0, 45, 3, 1, 10381 }
88 /* exynos: return pll clock frequency */
89 static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
91 unsigned long m, p, s = 0, mask, fout;
95 * APLL_CON: MIDV [25:16]
96 * MPLL_CON: MIDV [25:16]
97 * EPLL_CON: MIDV [24:16]
98 * VPLL_CON: MIDV [24:16]
99 * BPLL_CON: MIDV [25:16]: Exynos5
101 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL)
106 m = (r >> 16) & mask;
113 freq = CONFIG_SYS_CLK_FREQ;
115 if (pllreg == EPLL) {
117 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
118 fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
119 } else if (pllreg == VPLL) {
124 * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
127 * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
130 * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
132 if (proid_is_exynos4210())
134 else if (proid_is_exynos4412())
136 else if (proid_is_exynos5250())
141 fout = (m + k / div) * (freq / (p * (1 << s)));
145 * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
147 * Exynos4412 / Exynos5250
148 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
150 if (proid_is_exynos4210())
151 fout = m * (freq / (p * (1 << s)));
153 fout = m * (freq / (p * (1 << (s - 1))));
159 /* exynos4: return pll clock frequency */
160 static unsigned long exynos4_get_pll_clk(int pllreg)
162 struct exynos4_clock *clk =
163 (struct exynos4_clock *)samsung_get_base_clock();
164 unsigned long r, k = 0;
168 r = readl(&clk->apll_con0);
171 r = readl(&clk->mpll_con0);
174 r = readl(&clk->epll_con0);
175 k = readl(&clk->epll_con1);
178 r = readl(&clk->vpll_con0);
179 k = readl(&clk->vpll_con1);
182 printf("Unsupported PLL (%d)\n", pllreg);
186 return exynos_get_pll_clk(pllreg, r, k);
189 /* exynos4x12: return pll clock frequency */
190 static unsigned long exynos4x12_get_pll_clk(int pllreg)
192 struct exynos4x12_clock *clk =
193 (struct exynos4x12_clock *)samsung_get_base_clock();
194 unsigned long r, k = 0;
198 r = readl(&clk->apll_con0);
201 r = readl(&clk->mpll_con0);
204 r = readl(&clk->epll_con0);
205 k = readl(&clk->epll_con1);
208 r = readl(&clk->vpll_con0);
209 k = readl(&clk->vpll_con1);
212 printf("Unsupported PLL (%d)\n", pllreg);
216 return exynos_get_pll_clk(pllreg, r, k);
219 /* exynos5: return pll clock frequency */
220 static unsigned long exynos5_get_pll_clk(int pllreg)
222 struct exynos5_clock *clk =
223 (struct exynos5_clock *)samsung_get_base_clock();
224 unsigned long r, k = 0, fout;
225 unsigned int pll_div2_sel, fout_sel;
229 r = readl(&clk->apll_con0);
232 r = readl(&clk->mpll_con0);
235 r = readl(&clk->epll_con0);
236 k = readl(&clk->epll_con1);
239 r = readl(&clk->vpll_con0);
240 k = readl(&clk->vpll_con1);
243 r = readl(&clk->bpll_con0);
246 printf("Unsupported PLL (%d)\n", pllreg);
250 fout = exynos_get_pll_clk(pllreg, r, k);
252 /* According to the user manual, in EVT1 MPLL and BPLL always gives
253 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
254 if (pllreg == MPLL || pllreg == BPLL) {
255 pll_div2_sel = readl(&clk->pll_div2_sel);
259 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
260 & MPLL_FOUT_SEL_MASK;
263 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
264 & BPLL_FOUT_SEL_MASK;
278 static unsigned long exynos5_get_periph_rate(int peripheral)
280 struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
281 unsigned long sclk, sub_clk;
282 unsigned int src, div, sub_div;
283 struct exynos5_clock *clk =
284 (struct exynos5_clock *)samsung_get_base_clock();
286 switch (peripheral) {
287 case PERIPH_ID_UART0:
288 case PERIPH_ID_UART1:
289 case PERIPH_ID_UART2:
290 case PERIPH_ID_UART3:
291 src = readl(&clk->src_peric0);
292 div = readl(&clk->div_peric0);
299 src = readl(&clk->src_peric0);
300 div = readl(&clk->div_peric3);
304 src = readl(&clk->src_peric1);
305 div = readl(&clk->div_peric1);
308 src = readl(&clk->src_peric1);
309 div = readl(&clk->div_peric2);
313 src = readl(&clk->sclk_src_isp);
314 div = readl(&clk->sclk_div_isp);
316 case PERIPH_ID_SDMMC0:
317 case PERIPH_ID_SDMMC1:
318 case PERIPH_ID_SDMMC2:
319 case PERIPH_ID_SDMMC3:
320 src = readl(&clk->src_fsys);
321 div = readl(&clk->div_fsys1);
331 sclk = exynos5_get_pll_clk(MPLL);
332 sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit)
334 div = ((readl(&clk->div_top0) >> bit_info->prediv_bit)
336 return (sclk / sub_div) / div;
338 debug("%s: invalid peripheral %d", __func__, peripheral);
342 src = (src >> bit_info->src_bit) & 0xf;
345 case EXYNOS_SRC_MPLL:
346 sclk = exynos5_get_pll_clk(MPLL);
348 case EXYNOS_SRC_EPLL:
349 sclk = exynos5_get_pll_clk(EPLL);
351 case EXYNOS_SRC_VPLL:
352 sclk = exynos5_get_pll_clk(VPLL);
358 /* Ratio clock division for this peripheral */
359 sub_div = (div >> bit_info->div_bit) & 0xf;
360 sub_clk = sclk / (sub_div + 1);
362 /* Pre-ratio clock division for SDMMC0 and 2 */
363 if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
364 div = (div >> bit_info->prediv_bit) & 0xff;
365 return sub_clk / (div + 1);
371 unsigned long clock_get_periph_rate(int peripheral)
373 if (cpu_is_exynos5())
374 return exynos5_get_periph_rate(peripheral);
379 /* exynos4: return ARM clock frequency */
380 static unsigned long exynos4_get_arm_clk(void)
382 struct exynos4_clock *clk =
383 (struct exynos4_clock *)samsung_get_base_clock();
385 unsigned long armclk;
386 unsigned int core_ratio;
387 unsigned int core2_ratio;
389 div = readl(&clk->div_cpu0);
391 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
392 core_ratio = (div >> 0) & 0x7;
393 core2_ratio = (div >> 28) & 0x7;
395 armclk = get_pll_clk(APLL) / (core_ratio + 1);
396 armclk /= (core2_ratio + 1);
401 /* exynos4x12: return ARM clock frequency */
402 static unsigned long exynos4x12_get_arm_clk(void)
404 struct exynos4x12_clock *clk =
405 (struct exynos4x12_clock *)samsung_get_base_clock();
407 unsigned long armclk;
408 unsigned int core_ratio;
409 unsigned int core2_ratio;
411 div = readl(&clk->div_cpu0);
413 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
414 core_ratio = (div >> 0) & 0x7;
415 core2_ratio = (div >> 28) & 0x7;
417 armclk = get_pll_clk(APLL) / (core_ratio + 1);
418 armclk /= (core2_ratio + 1);
423 /* exynos5: return ARM clock frequency */
424 static unsigned long exynos5_get_arm_clk(void)
426 struct exynos5_clock *clk =
427 (struct exynos5_clock *)samsung_get_base_clock();
429 unsigned long armclk;
430 unsigned int arm_ratio;
431 unsigned int arm2_ratio;
433 div = readl(&clk->div_cpu0);
435 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
436 arm_ratio = (div >> 0) & 0x7;
437 arm2_ratio = (div >> 28) & 0x7;
439 armclk = get_pll_clk(APLL) / (arm_ratio + 1);
440 armclk /= (arm2_ratio + 1);
445 /* exynos4: return pwm clock frequency */
446 static unsigned long exynos4_get_pwm_clk(void)
448 struct exynos4_clock *clk =
449 (struct exynos4_clock *)samsung_get_base_clock();
450 unsigned long pclk, sclk;
454 if (s5p_get_cpu_rev() == 0) {
459 sel = readl(&clk->src_peril0);
460 sel = (sel >> 24) & 0xf;
463 sclk = get_pll_clk(MPLL);
465 sclk = get_pll_clk(EPLL);
467 sclk = get_pll_clk(VPLL);
475 ratio = readl(&clk->div_peril3);
477 } else if (s5p_get_cpu_rev() == 1) {
478 sclk = get_pll_clk(MPLL);
483 pclk = sclk / (ratio + 1);
488 /* exynos4x12: return pwm clock frequency */
489 static unsigned long exynos4x12_get_pwm_clk(void)
491 unsigned long pclk, sclk;
494 sclk = get_pll_clk(MPLL);
497 pclk = sclk / (ratio + 1);
502 /* exynos4: return uart clock frequency */
503 static unsigned long exynos4_get_uart_clk(int dev_index)
505 struct exynos4_clock *clk =
506 (struct exynos4_clock *)samsung_get_base_clock();
507 unsigned long uclk, sclk;
520 sel = readl(&clk->src_peril0);
521 sel = (sel >> (dev_index << 2)) & 0xf;
524 sclk = get_pll_clk(MPLL);
526 sclk = get_pll_clk(EPLL);
528 sclk = get_pll_clk(VPLL);
537 * UART3_RATIO [12:15]
538 * UART4_RATIO [16:19]
539 * UART5_RATIO [23:20]
541 ratio = readl(&clk->div_peril0);
542 ratio = (ratio >> (dev_index << 2)) & 0xf;
544 uclk = sclk / (ratio + 1);
549 /* exynos4x12: return uart clock frequency */
550 static unsigned long exynos4x12_get_uart_clk(int dev_index)
552 struct exynos4x12_clock *clk =
553 (struct exynos4x12_clock *)samsung_get_base_clock();
554 unsigned long uclk, sclk;
566 sel = readl(&clk->src_peril0);
567 sel = (sel >> (dev_index << 2)) & 0xf;
570 sclk = get_pll_clk(MPLL);
572 sclk = get_pll_clk(EPLL);
574 sclk = get_pll_clk(VPLL);
583 * UART3_RATIO [12:15]
584 * UART4_RATIO [16:19]
586 ratio = readl(&clk->div_peril0);
587 ratio = (ratio >> (dev_index << 2)) & 0xf;
589 uclk = sclk / (ratio + 1);
594 /* exynos5: return uart clock frequency */
595 static unsigned long exynos5_get_uart_clk(int dev_index)
597 struct exynos5_clock *clk =
598 (struct exynos5_clock *)samsung_get_base_clock();
599 unsigned long uclk, sclk;
612 sel = readl(&clk->src_peric0);
613 sel = (sel >> (dev_index << 2)) & 0xf;
616 sclk = get_pll_clk(MPLL);
618 sclk = get_pll_clk(EPLL);
620 sclk = get_pll_clk(VPLL);
629 * UART3_RATIO [12:15]
630 * UART4_RATIO [16:19]
631 * UART5_RATIO [23:20]
633 ratio = readl(&clk->div_peric0);
634 ratio = (ratio >> (dev_index << 2)) & 0xf;
636 uclk = sclk / (ratio + 1);
641 static unsigned long exynos4_get_mmc_clk(int dev_index)
643 struct exynos4_clock *clk =
644 (struct exynos4_clock *)samsung_get_base_clock();
645 unsigned long uclk, sclk;
646 unsigned int sel, ratio, pre_ratio;
649 sel = readl(&clk->src_fsys);
650 sel = (sel >> (dev_index << 2)) & 0xf;
653 sclk = get_pll_clk(MPLL);
655 sclk = get_pll_clk(EPLL);
657 sclk = get_pll_clk(VPLL);
664 ratio = readl(&clk->div_fsys1);
665 pre_ratio = readl(&clk->div_fsys1);
669 ratio = readl(&clk->div_fsys2);
670 pre_ratio = readl(&clk->div_fsys2);
673 ratio = readl(&clk->div_fsys3);
674 pre_ratio = readl(&clk->div_fsys3);
680 if (dev_index == 1 || dev_index == 3)
683 ratio = (ratio >> shift) & 0xf;
684 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
685 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
690 static unsigned long exynos5_get_mmc_clk(int dev_index)
692 struct exynos5_clock *clk =
693 (struct exynos5_clock *)samsung_get_base_clock();
694 unsigned long uclk, sclk;
695 unsigned int sel, ratio, pre_ratio;
698 sel = readl(&clk->src_fsys);
699 sel = (sel >> (dev_index << 2)) & 0xf;
702 sclk = get_pll_clk(MPLL);
704 sclk = get_pll_clk(EPLL);
706 sclk = get_pll_clk(VPLL);
713 ratio = readl(&clk->div_fsys1);
714 pre_ratio = readl(&clk->div_fsys1);
718 ratio = readl(&clk->div_fsys2);
719 pre_ratio = readl(&clk->div_fsys2);
725 if (dev_index == 1 || dev_index == 3)
728 ratio = (ratio >> shift) & 0xf;
729 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
730 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
735 /* exynos4: set the mmc clock */
736 static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
738 struct exynos4_clock *clk =
739 (struct exynos4_clock *)samsung_get_base_clock();
745 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
747 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
749 * MMC4_PRE_RATIO [15:8]
752 addr = (unsigned int)&clk->div_fsys1;
753 } else if (dev_index == 4) {
754 addr = (unsigned int)&clk->div_fsys3;
757 addr = (unsigned int)&clk->div_fsys2;
762 val &= ~(0xff << ((dev_index << 4) + 8));
763 val |= (div & 0xff) << ((dev_index << 4) + 8);
767 /* exynos4x12: set the mmc clock */
768 static void exynos4x12_set_mmc_clk(int dev_index, unsigned int div)
770 struct exynos4x12_clock *clk =
771 (struct exynos4x12_clock *)samsung_get_base_clock();
777 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
779 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
782 addr = (unsigned int)&clk->div_fsys1;
784 addr = (unsigned int)&clk->div_fsys2;
789 val &= ~(0xff << ((dev_index << 4) + 8));
790 val |= (div & 0xff) << ((dev_index << 4) + 8);
794 /* exynos5: set the mmc clock */
795 static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
797 struct exynos5_clock *clk =
798 (struct exynos5_clock *)samsung_get_base_clock();
804 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
806 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
809 addr = (unsigned int)&clk->div_fsys1;
811 addr = (unsigned int)&clk->div_fsys2;
816 val &= ~(0xff << ((dev_index << 4) + 8));
817 val |= (div & 0xff) << ((dev_index << 4) + 8);
821 /* get_lcd_clk: return lcd clock frequency */
822 static unsigned long exynos4_get_lcd_clk(void)
824 struct exynos4_clock *clk =
825 (struct exynos4_clock *)samsung_get_base_clock();
826 unsigned long pclk, sclk;
834 sel = readl(&clk->src_lcd0);
843 sclk = get_pll_clk(MPLL);
845 sclk = get_pll_clk(EPLL);
847 sclk = get_pll_clk(VPLL);
855 ratio = readl(&clk->div_lcd0);
858 pclk = sclk / (ratio + 1);
863 /* get_lcd_clk: return lcd clock frequency */
864 static unsigned long exynos5_get_lcd_clk(void)
866 struct exynos5_clock *clk =
867 (struct exynos5_clock *)samsung_get_base_clock();
868 unsigned long pclk, sclk;
876 sel = readl(&clk->src_disp1_0);
885 sclk = get_pll_clk(MPLL);
887 sclk = get_pll_clk(EPLL);
889 sclk = get_pll_clk(VPLL);
897 ratio = readl(&clk->div_disp1_0);
900 pclk = sclk / (ratio + 1);
905 void exynos4_set_lcd_clk(void)
907 struct exynos4_clock *clk =
908 (struct exynos4_clock *)samsung_get_base_clock();
909 unsigned int cfg = 0;
921 cfg = readl(&clk->gate_block);
923 writel(cfg, &clk->gate_block);
929 * MDNIE_PWM0_SEL [8:11]
931 * set lcd0 src clock 0x6: SCLK_MPLL
933 cfg = readl(&clk->src_lcd0);
936 writel(cfg, &clk->src_lcd0);
946 * Gating all clocks for FIMD0
948 cfg = readl(&clk->gate_ip_lcd0);
950 writel(cfg, &clk->gate_ip_lcd0);
956 * MDNIE_PWM0_RATIO [11:8]
957 * MDNIE_PWM_PRE_RATIO [15:12]
958 * MIPI0_RATIO [19:16]
959 * MIPI0_PRE_RATIO [23:20]
964 writel(cfg, &clk->div_lcd0);
967 void exynos5_set_lcd_clk(void)
969 struct exynos5_clock *clk =
970 (struct exynos5_clock *)samsung_get_base_clock();
971 unsigned int cfg = 0;
983 cfg = readl(&clk->gate_block);
985 writel(cfg, &clk->gate_block);
991 * MDNIE_PWM0_SEL [8:11]
993 * set lcd0 src clock 0x6: SCLK_MPLL
995 cfg = readl(&clk->src_disp1_0);
998 writel(cfg, &clk->src_disp1_0);
1008 * Gating all clocks for FIMD0
1010 cfg = readl(&clk->gate_ip_disp1);
1012 writel(cfg, &clk->gate_ip_disp1);
1017 * MDNIE0_RATIO [7:4]
1018 * MDNIE_PWM0_RATIO [11:8]
1019 * MDNIE_PWM_PRE_RATIO [15:12]
1020 * MIPI0_RATIO [19:16]
1021 * MIPI0_PRE_RATIO [23:20]
1026 writel(cfg, &clk->div_disp1_0);
1029 void exynos4_set_mipi_clk(void)
1031 struct exynos4_clock *clk =
1032 (struct exynos4_clock *)samsung_get_base_clock();
1033 unsigned int cfg = 0;
1039 * MDNIE_PWM0_SEL [8:11]
1041 * set mipi0 src clock 0x6: SCLK_MPLL
1043 cfg = readl(&clk->src_lcd0);
1044 cfg &= ~(0xf << 12);
1046 writel(cfg, &clk->src_lcd0);
1052 * MDNIE_PWM0_MASK [8]
1054 * set src mask mipi0 0x1: Unmask
1056 cfg = readl(&clk->src_mask_lcd0);
1058 writel(cfg, &clk->src_mask_lcd0);
1068 * Gating all clocks for MIPI0
1070 cfg = readl(&clk->gate_ip_lcd0);
1072 writel(cfg, &clk->gate_ip_lcd0);
1077 * MDNIE0_RATIO [7:4]
1078 * MDNIE_PWM0_RATIO [11:8]
1079 * MDNIE_PWM_PRE_RATIO [15:12]
1080 * MIPI0_RATIO [19:16]
1081 * MIPI0_PRE_RATIO [23:20]
1084 cfg &= ~(0xf << 16);
1086 writel(cfg, &clk->div_lcd0);
1092 * exynos5: obtaining the I2C clock
1094 static unsigned long exynos5_get_i2c_clk(void)
1096 struct exynos5_clock *clk =
1097 (struct exynos5_clock *)samsung_get_base_clock();
1098 unsigned long aclk_66, aclk_66_pre, sclk;
1101 sclk = get_pll_clk(MPLL);
1103 ratio = (readl(&clk->div_top1)) >> 24;
1105 aclk_66_pre = sclk / (ratio + 1);
1106 ratio = readl(&clk->div_top0);
1108 aclk_66 = aclk_66_pre / (ratio + 1);
1112 int exynos5_set_epll_clk(unsigned long rate)
1114 unsigned int epll_con, epll_con_k;
1116 unsigned int lockcnt;
1118 struct exynos5_clock *clk =
1119 (struct exynos5_clock *)samsung_get_base_clock();
1121 epll_con = readl(&clk->epll_con0);
1122 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1123 EPLL_CON0_LOCK_DET_EN_SHIFT) |
1124 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1125 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1126 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1128 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1129 if (exynos5_epll_div[i].freq_out == rate)
1133 if (i == ARRAY_SIZE(exynos5_epll_div))
1136 epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1137 epll_con |= exynos5_epll_div[i].en_lock_det <<
1138 EPLL_CON0_LOCK_DET_EN_SHIFT;
1139 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1140 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1141 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1144 * Required period ( in cycles) to genarate a stable clock output.
1145 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1146 * frequency input (as per spec)
1148 lockcnt = 3000 * exynos5_epll_div[i].p_div;
1150 writel(lockcnt, &clk->epll_lock);
1151 writel(epll_con, &clk->epll_con0);
1152 writel(epll_con_k, &clk->epll_con1);
1154 start = get_timer(0);
1156 while (!(readl(&clk->epll_con0) &
1157 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1158 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1159 debug("%s: Timeout waiting for EPLL lock\n", __func__);
1166 void exynos5_set_i2s_clk_source(void)
1168 struct exynos5_clock *clk =
1169 (struct exynos5_clock *)samsung_get_base_clock();
1171 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1172 (CLK_SRC_SCLK_EPLL));
1175 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
1176 unsigned int dst_frq)
1178 struct exynos5_clock *clk =
1179 (struct exynos5_clock *)samsung_get_base_clock();
1182 if ((dst_frq == 0) || (src_frq == 0)) {
1183 debug("%s: Invalid requency input for prescaler\n", __func__);
1184 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1188 div = (src_frq / dst_frq);
1189 if (div > AUDIO_1_RATIO_MASK) {
1190 debug("%s: Frequency ratio is out of range\n", __func__);
1191 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1194 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1195 (div & AUDIO_1_RATIO_MASK));
1200 * Linearly searches for the most accurate main and fine stage clock scalars
1201 * (divisors) for a specified target frequency and scalar bit sizes by checking
1202 * all multiples of main_scalar_bits values. Will always return scalars up to or
1203 * slower than target.
1205 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
1206 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
1207 * @param input_freq Clock frequency to be scaled in Hz
1208 * @param target_freq Desired clock frequency in Hz
1209 * @param best_fine_scalar Pointer to store the fine stage divisor
1211 * @return best_main_scalar Main scalar for desired frequency or -1 if none
1214 static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1215 unsigned int fine_scalar_bits, unsigned int input_rate,
1216 unsigned int target_rate, unsigned int *best_fine_scalar)
1219 int best_main_scalar = -1;
1220 unsigned int best_error = target_rate;
1221 const unsigned int cap = (1 << fine_scalar_bits) - 1;
1222 const unsigned int loops = 1 << main_scaler_bits;
1224 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1227 assert(best_fine_scalar != NULL);
1228 assert(main_scaler_bits <= fine_scalar_bits);
1230 *best_fine_scalar = 1;
1232 if (input_rate == 0 || target_rate == 0)
1235 if (target_rate >= input_rate)
1238 for (i = 1; i <= loops; i++) {
1239 const unsigned int effective_div = max(min(input_rate / i /
1240 target_rate, cap), 1);
1241 const unsigned int effective_rate = input_rate / i /
1243 const int error = target_rate - effective_rate;
1245 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1246 effective_rate, error);
1248 if (error >= 0 && error <= best_error) {
1250 best_main_scalar = i;
1251 *best_fine_scalar = effective_div;
1255 return best_main_scalar;
1258 static int exynos5_set_spi_clk(enum periph_id periph_id,
1261 struct exynos5_clock *clk =
1262 (struct exynos5_clock *)samsung_get_base_clock();
1265 unsigned shift, pre_shift;
1266 unsigned mask = 0xff;
1269 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1271 debug("%s: Cannot set clock rate for periph %d",
1272 __func__, periph_id);
1278 switch (periph_id) {
1279 case PERIPH_ID_SPI0:
1280 reg = &clk->div_peric1;
1284 case PERIPH_ID_SPI1:
1285 reg = &clk->div_peric1;
1289 case PERIPH_ID_SPI2:
1290 reg = &clk->div_peric2;
1294 case PERIPH_ID_SPI3:
1295 reg = &clk->sclk_div_isp;
1299 case PERIPH_ID_SPI4:
1300 reg = &clk->sclk_div_isp;
1305 debug("%s: Unsupported peripheral ID %d\n", __func__,
1309 clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1310 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1315 static unsigned long exynos4_get_i2c_clk(void)
1317 struct exynos4_clock *clk =
1318 (struct exynos4_clock *)samsung_get_base_clock();
1319 unsigned long sclk, aclk_100;
1322 sclk = get_pll_clk(APLL);
1324 ratio = (readl(&clk->div_top)) >> 4;
1326 aclk_100 = sclk / (ratio + 1);
1330 unsigned long get_pll_clk(int pllreg)
1332 if (cpu_is_exynos5())
1333 return exynos5_get_pll_clk(pllreg);
1335 if (proid_is_exynos4412())
1336 return exynos4x12_get_pll_clk(pllreg);
1337 return exynos4_get_pll_clk(pllreg);
1341 unsigned long get_arm_clk(void)
1343 if (cpu_is_exynos5())
1344 return exynos5_get_arm_clk();
1346 if (proid_is_exynos4412())
1347 return exynos4x12_get_arm_clk();
1348 return exynos4_get_arm_clk();
1352 unsigned long get_i2c_clk(void)
1354 if (cpu_is_exynos5()) {
1355 return exynos5_get_i2c_clk();
1356 } else if (cpu_is_exynos4()) {
1357 return exynos4_get_i2c_clk();
1359 debug("I2C clock is not set for this CPU\n");
1364 unsigned long get_pwm_clk(void)
1366 if (cpu_is_exynos5())
1367 return clock_get_periph_rate(PERIPH_ID_PWM0);
1369 if (proid_is_exynos4412())
1370 return exynos4x12_get_pwm_clk();
1371 return exynos4_get_pwm_clk();
1375 unsigned long get_uart_clk(int dev_index)
1377 if (cpu_is_exynos5())
1378 return exynos5_get_uart_clk(dev_index);
1380 if (proid_is_exynos4412())
1381 return exynos4x12_get_uart_clk(dev_index);
1382 return exynos4_get_uart_clk(dev_index);
1386 unsigned long get_mmc_clk(int dev_index)
1388 if (cpu_is_exynos5())
1389 return exynos5_get_mmc_clk(dev_index);
1391 return exynos4_get_mmc_clk(dev_index);
1394 void set_mmc_clk(int dev_index, unsigned int div)
1396 if (cpu_is_exynos5())
1397 exynos5_set_mmc_clk(dev_index, div);
1399 if (proid_is_exynos4412())
1400 exynos4x12_set_mmc_clk(dev_index, div);
1401 exynos4_set_mmc_clk(dev_index, div);
1405 unsigned long get_lcd_clk(void)
1407 if (cpu_is_exynos4())
1408 return exynos4_get_lcd_clk();
1410 return exynos5_get_lcd_clk();
1413 void set_lcd_clk(void)
1415 if (cpu_is_exynos4())
1416 exynos4_set_lcd_clk();
1418 exynos5_set_lcd_clk();
1421 void set_mipi_clk(void)
1423 if (cpu_is_exynos4())
1424 exynos4_set_mipi_clk();
1427 int set_spi_clk(int periph_id, unsigned int rate)
1429 if (cpu_is_exynos5())
1430 return exynos5_set_spi_clk(periph_id, rate);
1435 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
1438 if (cpu_is_exynos5())
1439 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq);
1444 void set_i2s_clk_source(void)
1446 if (cpu_is_exynos5())
1447 exynos5_set_i2s_clk_source();
1450 int set_epll_clk(unsigned long rate)
1452 if (cpu_is_exynos5())
1453 return exynos5_set_epll_clk(rate);