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)));
144 * Exynos4412 / Exynos5250
145 * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
148 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
150 if (proid_is_exynos4210())
151 fout = m * (freq / (p * (1 << (s - 1))));
153 fout = m * (freq / (p * (1 << s)));
158 /* exynos4: return pll clock frequency */
159 static unsigned long exynos4_get_pll_clk(int pllreg)
161 struct exynos4_clock *clk =
162 (struct exynos4_clock *)samsung_get_base_clock();
163 unsigned long r, k = 0;
167 r = readl(&clk->apll_con0);
170 r = readl(&clk->mpll_con0);
173 r = readl(&clk->epll_con0);
174 k = readl(&clk->epll_con1);
177 r = readl(&clk->vpll_con0);
178 k = readl(&clk->vpll_con1);
181 printf("Unsupported PLL (%d)\n", pllreg);
185 return exynos_get_pll_clk(pllreg, r, k);
188 /* exynos4x12: return pll clock frequency */
189 static unsigned long exynos4x12_get_pll_clk(int pllreg)
191 struct exynos4x12_clock *clk =
192 (struct exynos4x12_clock *)samsung_get_base_clock();
193 unsigned long r, k = 0;
197 r = readl(&clk->apll_con0);
200 r = readl(&clk->mpll_con0);
203 r = readl(&clk->epll_con0);
204 k = readl(&clk->epll_con1);
207 r = readl(&clk->vpll_con0);
208 k = readl(&clk->vpll_con1);
211 printf("Unsupported PLL (%d)\n", pllreg);
215 return exynos_get_pll_clk(pllreg, r, k);
218 /* exynos5: return pll clock frequency */
219 static unsigned long exynos5_get_pll_clk(int pllreg)
221 struct exynos5_clock *clk =
222 (struct exynos5_clock *)samsung_get_base_clock();
223 unsigned long r, k = 0, fout;
224 unsigned int pll_div2_sel, fout_sel;
228 r = readl(&clk->apll_con0);
231 r = readl(&clk->mpll_con0);
234 r = readl(&clk->epll_con0);
235 k = readl(&clk->epll_con1);
238 r = readl(&clk->vpll_con0);
239 k = readl(&clk->vpll_con1);
242 r = readl(&clk->bpll_con0);
245 printf("Unsupported PLL (%d)\n", pllreg);
249 fout = exynos_get_pll_clk(pllreg, r, k);
251 /* According to the user manual, in EVT1 MPLL and BPLL always gives
252 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
253 if (pllreg == MPLL || pllreg == BPLL) {
254 pll_div2_sel = readl(&clk->pll_div2_sel);
258 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
259 & MPLL_FOUT_SEL_MASK;
262 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
263 & BPLL_FOUT_SEL_MASK;
277 static unsigned long exynos5_get_periph_rate(int peripheral)
279 struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
280 unsigned long sclk, sub_clk;
281 unsigned int src, div, sub_div;
282 struct exynos5_clock *clk =
283 (struct exynos5_clock *)samsung_get_base_clock();
285 switch (peripheral) {
286 case PERIPH_ID_UART0:
287 case PERIPH_ID_UART1:
288 case PERIPH_ID_UART2:
289 case PERIPH_ID_UART3:
290 src = readl(&clk->src_peric0);
291 div = readl(&clk->div_peric0);
298 src = readl(&clk->src_peric0);
299 div = readl(&clk->div_peric3);
303 src = readl(&clk->src_peric1);
304 div = readl(&clk->div_peric1);
307 src = readl(&clk->src_peric1);
308 div = readl(&clk->div_peric2);
312 src = readl(&clk->sclk_src_isp);
313 div = readl(&clk->sclk_div_isp);
315 case PERIPH_ID_SDMMC0:
316 case PERIPH_ID_SDMMC1:
317 case PERIPH_ID_SDMMC2:
318 case PERIPH_ID_SDMMC3:
319 src = readl(&clk->src_fsys);
320 div = readl(&clk->div_fsys1);
330 sclk = exynos5_get_pll_clk(MPLL);
331 sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit)
333 div = ((readl(&clk->div_top0) >> bit_info->prediv_bit)
335 return (sclk / sub_div) / div;
337 debug("%s: invalid peripheral %d", __func__, peripheral);
341 src = (src >> bit_info->src_bit) & 0xf;
344 case EXYNOS_SRC_MPLL:
345 sclk = exynos5_get_pll_clk(MPLL);
347 case EXYNOS_SRC_EPLL:
348 sclk = exynos5_get_pll_clk(EPLL);
350 case EXYNOS_SRC_VPLL:
351 sclk = exynos5_get_pll_clk(VPLL);
357 /* Ratio clock division for this peripheral */
358 sub_div = (div >> bit_info->div_bit) & 0xf;
359 sub_clk = sclk / (sub_div + 1);
361 /* Pre-ratio clock division for SDMMC0 and 2 */
362 if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
363 div = (div >> bit_info->prediv_bit) & 0xff;
364 return sub_clk / (div + 1);
370 unsigned long clock_get_periph_rate(int peripheral)
372 if (cpu_is_exynos5())
373 return exynos5_get_periph_rate(peripheral);
378 /* exynos4: return ARM clock frequency */
379 static unsigned long exynos4_get_arm_clk(void)
381 struct exynos4_clock *clk =
382 (struct exynos4_clock *)samsung_get_base_clock();
384 unsigned long armclk;
385 unsigned int core_ratio;
386 unsigned int core2_ratio;
388 div = readl(&clk->div_cpu0);
390 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
391 core_ratio = (div >> 0) & 0x7;
392 core2_ratio = (div >> 28) & 0x7;
394 armclk = get_pll_clk(APLL) / (core_ratio + 1);
395 armclk /= (core2_ratio + 1);
400 /* exynos4x12: return ARM clock frequency */
401 static unsigned long exynos4x12_get_arm_clk(void)
403 struct exynos4x12_clock *clk =
404 (struct exynos4x12_clock *)samsung_get_base_clock();
406 unsigned long armclk;
407 unsigned int core_ratio;
408 unsigned int core2_ratio;
410 div = readl(&clk->div_cpu0);
412 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
413 core_ratio = (div >> 0) & 0x7;
414 core2_ratio = (div >> 28) & 0x7;
416 armclk = get_pll_clk(APLL) / (core_ratio + 1);
417 armclk /= (core2_ratio + 1);
422 /* exynos5: return ARM clock frequency */
423 static unsigned long exynos5_get_arm_clk(void)
425 struct exynos5_clock *clk =
426 (struct exynos5_clock *)samsung_get_base_clock();
428 unsigned long armclk;
429 unsigned int arm_ratio;
430 unsigned int arm2_ratio;
432 div = readl(&clk->div_cpu0);
434 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
435 arm_ratio = (div >> 0) & 0x7;
436 arm2_ratio = (div >> 28) & 0x7;
438 armclk = get_pll_clk(APLL) / (arm_ratio + 1);
439 armclk /= (arm2_ratio + 1);
444 /* exynos4: return pwm clock frequency */
445 static unsigned long exynos4_get_pwm_clk(void)
447 struct exynos4_clock *clk =
448 (struct exynos4_clock *)samsung_get_base_clock();
449 unsigned long pclk, sclk;
453 if (s5p_get_cpu_rev() == 0) {
458 sel = readl(&clk->src_peril0);
459 sel = (sel >> 24) & 0xf;
462 sclk = get_pll_clk(MPLL);
464 sclk = get_pll_clk(EPLL);
466 sclk = get_pll_clk(VPLL);
474 ratio = readl(&clk->div_peril3);
476 } else if (s5p_get_cpu_rev() == 1) {
477 sclk = get_pll_clk(MPLL);
482 pclk = sclk / (ratio + 1);
487 /* exynos4x12: return pwm clock frequency */
488 static unsigned long exynos4x12_get_pwm_clk(void)
490 unsigned long pclk, sclk;
493 sclk = get_pll_clk(MPLL);
496 pclk = sclk / (ratio + 1);
501 /* exynos4: return uart clock frequency */
502 static unsigned long exynos4_get_uart_clk(int dev_index)
504 struct exynos4_clock *clk =
505 (struct exynos4_clock *)samsung_get_base_clock();
506 unsigned long uclk, sclk;
519 sel = readl(&clk->src_peril0);
520 sel = (sel >> (dev_index << 2)) & 0xf;
523 sclk = get_pll_clk(MPLL);
525 sclk = get_pll_clk(EPLL);
527 sclk = get_pll_clk(VPLL);
536 * UART3_RATIO [12:15]
537 * UART4_RATIO [16:19]
538 * UART5_RATIO [23:20]
540 ratio = readl(&clk->div_peril0);
541 ratio = (ratio >> (dev_index << 2)) & 0xf;
543 uclk = sclk / (ratio + 1);
548 /* exynos4x12: return uart clock frequency */
549 static unsigned long exynos4x12_get_uart_clk(int dev_index)
551 struct exynos4x12_clock *clk =
552 (struct exynos4x12_clock *)samsung_get_base_clock();
553 unsigned long uclk, sclk;
565 sel = readl(&clk->src_peril0);
566 sel = (sel >> (dev_index << 2)) & 0xf;
569 sclk = get_pll_clk(MPLL);
571 sclk = get_pll_clk(EPLL);
573 sclk = get_pll_clk(VPLL);
582 * UART3_RATIO [12:15]
583 * UART4_RATIO [16:19]
585 ratio = readl(&clk->div_peril0);
586 ratio = (ratio >> (dev_index << 2)) & 0xf;
588 uclk = sclk / (ratio + 1);
593 /* exynos5: return uart clock frequency */
594 static unsigned long exynos5_get_uart_clk(int dev_index)
596 struct exynos5_clock *clk =
597 (struct exynos5_clock *)samsung_get_base_clock();
598 unsigned long uclk, sclk;
611 sel = readl(&clk->src_peric0);
612 sel = (sel >> (dev_index << 2)) & 0xf;
615 sclk = get_pll_clk(MPLL);
617 sclk = get_pll_clk(EPLL);
619 sclk = get_pll_clk(VPLL);
628 * UART3_RATIO [12:15]
629 * UART4_RATIO [16:19]
630 * UART5_RATIO [23:20]
632 ratio = readl(&clk->div_peric0);
633 ratio = (ratio >> (dev_index << 2)) & 0xf;
635 uclk = sclk / (ratio + 1);
640 static unsigned long exynos4_get_mmc_clk(int dev_index)
642 struct exynos4_clock *clk =
643 (struct exynos4_clock *)samsung_get_base_clock();
644 unsigned long uclk, sclk;
645 unsigned int sel, ratio, pre_ratio;
648 sel = readl(&clk->src_fsys);
649 sel = (sel >> (dev_index << 2)) & 0xf;
652 sclk = get_pll_clk(MPLL);
654 sclk = get_pll_clk(EPLL);
656 sclk = get_pll_clk(VPLL);
663 ratio = readl(&clk->div_fsys1);
664 pre_ratio = readl(&clk->div_fsys1);
668 ratio = readl(&clk->div_fsys2);
669 pre_ratio = readl(&clk->div_fsys2);
672 ratio = readl(&clk->div_fsys3);
673 pre_ratio = readl(&clk->div_fsys3);
679 if (dev_index == 1 || dev_index == 3)
682 ratio = (ratio >> shift) & 0xf;
683 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
684 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
689 static unsigned long exynos5_get_mmc_clk(int dev_index)
691 struct exynos5_clock *clk =
692 (struct exynos5_clock *)samsung_get_base_clock();
693 unsigned long uclk, sclk;
694 unsigned int sel, ratio, pre_ratio;
697 sel = readl(&clk->src_fsys);
698 sel = (sel >> (dev_index << 2)) & 0xf;
701 sclk = get_pll_clk(MPLL);
703 sclk = get_pll_clk(EPLL);
705 sclk = get_pll_clk(VPLL);
712 ratio = readl(&clk->div_fsys1);
713 pre_ratio = readl(&clk->div_fsys1);
717 ratio = readl(&clk->div_fsys2);
718 pre_ratio = readl(&clk->div_fsys2);
724 if (dev_index == 1 || dev_index == 3)
727 ratio = (ratio >> shift) & 0xf;
728 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
729 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
734 /* exynos4: set the mmc clock */
735 static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
737 struct exynos4_clock *clk =
738 (struct exynos4_clock *)samsung_get_base_clock();
744 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
746 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
748 * MMC4_PRE_RATIO [15:8]
751 addr = (unsigned int)&clk->div_fsys1;
752 } else if (dev_index == 4) {
753 addr = (unsigned int)&clk->div_fsys3;
756 addr = (unsigned int)&clk->div_fsys2;
761 val &= ~(0xff << ((dev_index << 4) + 8));
762 val |= (div & 0xff) << ((dev_index << 4) + 8);
766 /* exynos4x12: set the mmc clock */
767 static void exynos4x12_set_mmc_clk(int dev_index, unsigned int div)
769 struct exynos4x12_clock *clk =
770 (struct exynos4x12_clock *)samsung_get_base_clock();
776 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
778 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
781 addr = (unsigned int)&clk->div_fsys1;
783 addr = (unsigned int)&clk->div_fsys2;
788 val &= ~(0xff << ((dev_index << 4) + 8));
789 val |= (div & 0xff) << ((dev_index << 4) + 8);
793 /* exynos5: set the mmc clock */
794 static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
796 struct exynos5_clock *clk =
797 (struct exynos5_clock *)samsung_get_base_clock();
803 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
805 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
808 addr = (unsigned int)&clk->div_fsys1;
810 addr = (unsigned int)&clk->div_fsys2;
815 val &= ~(0xff << ((dev_index << 4) + 8));
816 val |= (div & 0xff) << ((dev_index << 4) + 8);
820 /* get_lcd_clk: return lcd clock frequency */
821 static unsigned long exynos4_get_lcd_clk(void)
823 struct exynos4_clock *clk =
824 (struct exynos4_clock *)samsung_get_base_clock();
825 unsigned long pclk, sclk;
833 sel = readl(&clk->src_lcd0);
842 sclk = get_pll_clk(MPLL);
844 sclk = get_pll_clk(EPLL);
846 sclk = get_pll_clk(VPLL);
854 ratio = readl(&clk->div_lcd0);
857 pclk = sclk / (ratio + 1);
862 /* get_lcd_clk: return lcd clock frequency */
863 static unsigned long exynos5_get_lcd_clk(void)
865 struct exynos5_clock *clk =
866 (struct exynos5_clock *)samsung_get_base_clock();
867 unsigned long pclk, sclk;
875 sel = readl(&clk->src_disp1_0);
884 sclk = get_pll_clk(MPLL);
886 sclk = get_pll_clk(EPLL);
888 sclk = get_pll_clk(VPLL);
896 ratio = readl(&clk->div_disp1_0);
899 pclk = sclk / (ratio + 1);
904 void exynos4_set_lcd_clk(void)
906 struct exynos4_clock *clk =
907 (struct exynos4_clock *)samsung_get_base_clock();
908 unsigned int cfg = 0;
920 cfg = readl(&clk->gate_block);
922 writel(cfg, &clk->gate_block);
928 * MDNIE_PWM0_SEL [8:11]
930 * set lcd0 src clock 0x6: SCLK_MPLL
932 cfg = readl(&clk->src_lcd0);
935 writel(cfg, &clk->src_lcd0);
945 * Gating all clocks for FIMD0
947 cfg = readl(&clk->gate_ip_lcd0);
949 writel(cfg, &clk->gate_ip_lcd0);
955 * MDNIE_PWM0_RATIO [11:8]
956 * MDNIE_PWM_PRE_RATIO [15:12]
957 * MIPI0_RATIO [19:16]
958 * MIPI0_PRE_RATIO [23:20]
963 writel(cfg, &clk->div_lcd0);
966 void exynos5_set_lcd_clk(void)
968 struct exynos5_clock *clk =
969 (struct exynos5_clock *)samsung_get_base_clock();
970 unsigned int cfg = 0;
982 cfg = readl(&clk->gate_block);
984 writel(cfg, &clk->gate_block);
990 * MDNIE_PWM0_SEL [8:11]
992 * set lcd0 src clock 0x6: SCLK_MPLL
994 cfg = readl(&clk->src_disp1_0);
997 writel(cfg, &clk->src_disp1_0);
1007 * Gating all clocks for FIMD0
1009 cfg = readl(&clk->gate_ip_disp1);
1011 writel(cfg, &clk->gate_ip_disp1);
1016 * MDNIE0_RATIO [7:4]
1017 * MDNIE_PWM0_RATIO [11:8]
1018 * MDNIE_PWM_PRE_RATIO [15:12]
1019 * MIPI0_RATIO [19:16]
1020 * MIPI0_PRE_RATIO [23:20]
1025 writel(cfg, &clk->div_disp1_0);
1028 void exynos4_set_mipi_clk(void)
1030 struct exynos4_clock *clk =
1031 (struct exynos4_clock *)samsung_get_base_clock();
1032 unsigned int cfg = 0;
1038 * MDNIE_PWM0_SEL [8:11]
1040 * set mipi0 src clock 0x6: SCLK_MPLL
1042 cfg = readl(&clk->src_lcd0);
1043 cfg &= ~(0xf << 12);
1045 writel(cfg, &clk->src_lcd0);
1051 * MDNIE_PWM0_MASK [8]
1053 * set src mask mipi0 0x1: Unmask
1055 cfg = readl(&clk->src_mask_lcd0);
1057 writel(cfg, &clk->src_mask_lcd0);
1067 * Gating all clocks for MIPI0
1069 cfg = readl(&clk->gate_ip_lcd0);
1071 writel(cfg, &clk->gate_ip_lcd0);
1076 * MDNIE0_RATIO [7:4]
1077 * MDNIE_PWM0_RATIO [11:8]
1078 * MDNIE_PWM_PRE_RATIO [15:12]
1079 * MIPI0_RATIO [19:16]
1080 * MIPI0_PRE_RATIO [23:20]
1083 cfg &= ~(0xf << 16);
1085 writel(cfg, &clk->div_lcd0);
1091 * exynos5: obtaining the I2C clock
1093 static unsigned long exynos5_get_i2c_clk(void)
1095 struct exynos5_clock *clk =
1096 (struct exynos5_clock *)samsung_get_base_clock();
1097 unsigned long aclk_66, aclk_66_pre, sclk;
1100 sclk = get_pll_clk(MPLL);
1102 ratio = (readl(&clk->div_top1)) >> 24;
1104 aclk_66_pre = sclk / (ratio + 1);
1105 ratio = readl(&clk->div_top0);
1107 aclk_66 = aclk_66_pre / (ratio + 1);
1111 int exynos5_set_epll_clk(unsigned long rate)
1113 unsigned int epll_con, epll_con_k;
1115 unsigned int lockcnt;
1117 struct exynos5_clock *clk =
1118 (struct exynos5_clock *)samsung_get_base_clock();
1120 epll_con = readl(&clk->epll_con0);
1121 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1122 EPLL_CON0_LOCK_DET_EN_SHIFT) |
1123 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1124 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1125 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1127 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1128 if (exynos5_epll_div[i].freq_out == rate)
1132 if (i == ARRAY_SIZE(exynos5_epll_div))
1135 epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1136 epll_con |= exynos5_epll_div[i].en_lock_det <<
1137 EPLL_CON0_LOCK_DET_EN_SHIFT;
1138 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1139 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1140 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1143 * Required period ( in cycles) to genarate a stable clock output.
1144 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1145 * frequency input (as per spec)
1147 lockcnt = 3000 * exynos5_epll_div[i].p_div;
1149 writel(lockcnt, &clk->epll_lock);
1150 writel(epll_con, &clk->epll_con0);
1151 writel(epll_con_k, &clk->epll_con1);
1153 start = get_timer(0);
1155 while (!(readl(&clk->epll_con0) &
1156 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1157 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1158 debug("%s: Timeout waiting for EPLL lock\n", __func__);
1165 void exynos5_set_i2s_clk_source(void)
1167 struct exynos5_clock *clk =
1168 (struct exynos5_clock *)samsung_get_base_clock();
1170 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1171 (CLK_SRC_SCLK_EPLL));
1174 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
1175 unsigned int dst_frq)
1177 struct exynos5_clock *clk =
1178 (struct exynos5_clock *)samsung_get_base_clock();
1181 if ((dst_frq == 0) || (src_frq == 0)) {
1182 debug("%s: Invalid requency input for prescaler\n", __func__);
1183 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1187 div = (src_frq / dst_frq);
1188 if (div > AUDIO_1_RATIO_MASK) {
1189 debug("%s: Frequency ratio is out of range\n", __func__);
1190 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1193 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1194 (div & AUDIO_1_RATIO_MASK));
1199 * Linearly searches for the most accurate main and fine stage clock scalars
1200 * (divisors) for a specified target frequency and scalar bit sizes by checking
1201 * all multiples of main_scalar_bits values. Will always return scalars up to or
1202 * slower than target.
1204 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
1205 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
1206 * @param input_freq Clock frequency to be scaled in Hz
1207 * @param target_freq Desired clock frequency in Hz
1208 * @param best_fine_scalar Pointer to store the fine stage divisor
1210 * @return best_main_scalar Main scalar for desired frequency or -1 if none
1213 static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1214 unsigned int fine_scalar_bits, unsigned int input_rate,
1215 unsigned int target_rate, unsigned int *best_fine_scalar)
1218 int best_main_scalar = -1;
1219 unsigned int best_error = target_rate;
1220 const unsigned int cap = (1 << fine_scalar_bits) - 1;
1221 const unsigned int loops = 1 << main_scaler_bits;
1223 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1226 assert(best_fine_scalar != NULL);
1227 assert(main_scaler_bits <= fine_scalar_bits);
1229 *best_fine_scalar = 1;
1231 if (input_rate == 0 || target_rate == 0)
1234 if (target_rate >= input_rate)
1237 for (i = 1; i <= loops; i++) {
1238 const unsigned int effective_div = max(min(input_rate / i /
1239 target_rate, cap), 1);
1240 const unsigned int effective_rate = input_rate / i /
1242 const int error = target_rate - effective_rate;
1244 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1245 effective_rate, error);
1247 if (error >= 0 && error <= best_error) {
1249 best_main_scalar = i;
1250 *best_fine_scalar = effective_div;
1254 return best_main_scalar;
1257 static int exynos5_set_spi_clk(enum periph_id periph_id,
1260 struct exynos5_clock *clk =
1261 (struct exynos5_clock *)samsung_get_base_clock();
1264 unsigned shift, pre_shift;
1265 unsigned mask = 0xff;
1268 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1270 debug("%s: Cannot set clock rate for periph %d",
1271 __func__, periph_id);
1277 switch (periph_id) {
1278 case PERIPH_ID_SPI0:
1279 reg = &clk->div_peric1;
1283 case PERIPH_ID_SPI1:
1284 reg = &clk->div_peric1;
1288 case PERIPH_ID_SPI2:
1289 reg = &clk->div_peric2;
1293 case PERIPH_ID_SPI3:
1294 reg = &clk->sclk_div_isp;
1298 case PERIPH_ID_SPI4:
1299 reg = &clk->sclk_div_isp;
1304 debug("%s: Unsupported peripheral ID %d\n", __func__,
1308 clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1309 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1314 static unsigned long exynos4_get_i2c_clk(void)
1316 struct exynos4_clock *clk =
1317 (struct exynos4_clock *)samsung_get_base_clock();
1318 unsigned long sclk, aclk_100;
1321 sclk = get_pll_clk(APLL);
1323 ratio = (readl(&clk->div_top)) >> 4;
1325 aclk_100 = sclk / (ratio + 1);
1329 unsigned long get_pll_clk(int pllreg)
1331 if (cpu_is_exynos5())
1332 return exynos5_get_pll_clk(pllreg);
1334 if (proid_is_exynos4412())
1335 return exynos4x12_get_pll_clk(pllreg);
1336 return exynos4_get_pll_clk(pllreg);
1340 unsigned long get_arm_clk(void)
1342 if (cpu_is_exynos5())
1343 return exynos5_get_arm_clk();
1345 if (proid_is_exynos4412())
1346 return exynos4x12_get_arm_clk();
1347 return exynos4_get_arm_clk();
1351 unsigned long get_i2c_clk(void)
1353 if (cpu_is_exynos5()) {
1354 return exynos5_get_i2c_clk();
1355 } else if (cpu_is_exynos4()) {
1356 return exynos4_get_i2c_clk();
1358 debug("I2C clock is not set for this CPU\n");
1363 unsigned long get_pwm_clk(void)
1365 if (cpu_is_exynos5())
1366 return clock_get_periph_rate(PERIPH_ID_PWM0);
1368 if (proid_is_exynos4412())
1369 return exynos4x12_get_pwm_clk();
1370 return exynos4_get_pwm_clk();
1374 unsigned long get_uart_clk(int dev_index)
1376 if (cpu_is_exynos5())
1377 return exynos5_get_uart_clk(dev_index);
1379 if (proid_is_exynos4412())
1380 return exynos4x12_get_uart_clk(dev_index);
1381 return exynos4_get_uart_clk(dev_index);
1385 unsigned long get_mmc_clk(int dev_index)
1387 if (cpu_is_exynos5())
1388 return exynos5_get_mmc_clk(dev_index);
1390 return exynos4_get_mmc_clk(dev_index);
1393 void set_mmc_clk(int dev_index, unsigned int div)
1395 if (cpu_is_exynos5())
1396 exynos5_set_mmc_clk(dev_index, div);
1398 if (proid_is_exynos4412())
1399 exynos4x12_set_mmc_clk(dev_index, div);
1400 exynos4_set_mmc_clk(dev_index, div);
1404 unsigned long get_lcd_clk(void)
1406 if (cpu_is_exynos4())
1407 return exynos4_get_lcd_clk();
1409 return exynos5_get_lcd_clk();
1412 void set_lcd_clk(void)
1414 if (cpu_is_exynos4())
1415 exynos4_set_lcd_clk();
1417 exynos5_set_lcd_clk();
1420 void set_mipi_clk(void)
1422 if (cpu_is_exynos4())
1423 exynos4_set_mipi_clk();
1426 int set_spi_clk(int periph_id, unsigned int rate)
1428 if (cpu_is_exynos5())
1429 return exynos5_set_spi_clk(periph_id, rate);
1434 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
1437 if (cpu_is_exynos5())
1438 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq);
1443 void set_i2s_clk_source(void)
1445 if (cpu_is_exynos5())
1446 exynos5_set_i2s_clk_source();
1449 int set_epll_clk(unsigned long rate)
1451 if (cpu_is_exynos5())
1452 return exynos5_set_epll_clk(rate);