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 /* Epll Clock division values to achive different frequency output */
31 static struct set_epll_con_val exynos5_epll_div[] = {
32 { 192000000, 0, 48, 3, 1, 0 },
33 { 180000000, 0, 45, 3, 1, 0 },
34 { 73728000, 1, 73, 3, 3, 47710 },
35 { 67737600, 1, 90, 4, 3, 20762 },
36 { 49152000, 0, 49, 3, 3, 9961 },
37 { 45158400, 0, 45, 3, 3, 10381 },
38 { 180633600, 0, 45, 3, 1, 10381 }
41 /* exynos: return pll clock frequency */
42 static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
44 unsigned long m, p, s = 0, mask, fout;
47 * APLL_CON: MIDV [25:16]
48 * MPLL_CON: MIDV [25:16]
49 * EPLL_CON: MIDV [24:16]
50 * VPLL_CON: MIDV [24:16]
51 * BPLL_CON: MIDV [25:16]: Exynos5
53 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL)
65 freq = CONFIG_SYS_CLK_FREQ;
69 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
70 fout = (m + k / 65536) * (freq / (p * (1 << s)));
71 } else if (pllreg == VPLL) {
73 /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
74 fout = (m + k / 1024) * (freq / (p * (1 << s)));
78 /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
79 fout = m * (freq / (p * (1 << (s - 1))));
85 /* exynos4: return pll clock frequency */
86 static unsigned long exynos4_get_pll_clk(int pllreg)
88 struct exynos4_clock *clk =
89 (struct exynos4_clock *)samsung_get_base_clock();
90 unsigned long r, k = 0;
94 r = readl(&clk->apll_con0);
97 r = readl(&clk->mpll_con0);
100 r = readl(&clk->epll_con0);
101 k = readl(&clk->epll_con1);
104 r = readl(&clk->vpll_con0);
105 k = readl(&clk->vpll_con1);
108 printf("Unsupported PLL (%d)\n", pllreg);
112 return exynos_get_pll_clk(pllreg, r, k);
115 /* exynos5: return pll clock frequency */
116 static unsigned long exynos5_get_pll_clk(int pllreg)
118 struct exynos5_clock *clk =
119 (struct exynos5_clock *)samsung_get_base_clock();
120 unsigned long r, k = 0, fout;
121 unsigned int pll_div2_sel, fout_sel;
125 r = readl(&clk->apll_con0);
128 r = readl(&clk->mpll_con0);
131 r = readl(&clk->epll_con0);
132 k = readl(&clk->epll_con1);
135 r = readl(&clk->vpll_con0);
136 k = readl(&clk->vpll_con1);
139 r = readl(&clk->bpll_con0);
142 printf("Unsupported PLL (%d)\n", pllreg);
146 fout = exynos_get_pll_clk(pllreg, r, k);
148 /* According to the user manual, in EVT1 MPLL and BPLL always gives
149 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
150 if (pllreg == MPLL || pllreg == BPLL) {
151 pll_div2_sel = readl(&clk->pll_div2_sel);
155 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
156 & MPLL_FOUT_SEL_MASK;
159 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
160 & BPLL_FOUT_SEL_MASK;
174 /* exynos4: return ARM clock frequency */
175 static unsigned long exynos4_get_arm_clk(void)
177 struct exynos4_clock *clk =
178 (struct exynos4_clock *)samsung_get_base_clock();
180 unsigned long armclk;
181 unsigned int core_ratio;
182 unsigned int core2_ratio;
184 div = readl(&clk->div_cpu0);
186 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
187 core_ratio = (div >> 0) & 0x7;
188 core2_ratio = (div >> 28) & 0x7;
190 armclk = get_pll_clk(APLL) / (core_ratio + 1);
191 armclk /= (core2_ratio + 1);
196 /* exynos5: return ARM clock frequency */
197 static unsigned long exynos5_get_arm_clk(void)
199 struct exynos5_clock *clk =
200 (struct exynos5_clock *)samsung_get_base_clock();
202 unsigned long armclk;
203 unsigned int arm_ratio;
204 unsigned int arm2_ratio;
206 div = readl(&clk->div_cpu0);
208 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
209 arm_ratio = (div >> 0) & 0x7;
210 arm2_ratio = (div >> 28) & 0x7;
212 armclk = get_pll_clk(APLL) / (arm_ratio + 1);
213 armclk /= (arm2_ratio + 1);
218 /* exynos4: return pwm clock frequency */
219 static unsigned long exynos4_get_pwm_clk(void)
221 struct exynos4_clock *clk =
222 (struct exynos4_clock *)samsung_get_base_clock();
223 unsigned long pclk, sclk;
227 if (s5p_get_cpu_rev() == 0) {
232 sel = readl(&clk->src_peril0);
233 sel = (sel >> 24) & 0xf;
236 sclk = get_pll_clk(MPLL);
238 sclk = get_pll_clk(EPLL);
240 sclk = get_pll_clk(VPLL);
248 ratio = readl(&clk->div_peril3);
250 } else if (s5p_get_cpu_rev() == 1) {
251 sclk = get_pll_clk(MPLL);
256 pclk = sclk / (ratio + 1);
261 /* exynos5: return pwm clock frequency */
262 static unsigned long exynos5_get_pwm_clk(void)
264 struct exynos5_clock *clk =
265 (struct exynos5_clock *)samsung_get_base_clock();
266 unsigned long pclk, sclk;
273 ratio = readl(&clk->div_peric3);
275 sclk = get_pll_clk(MPLL);
277 pclk = sclk / (ratio + 1);
282 /* exynos4: return uart clock frequency */
283 static unsigned long exynos4_get_uart_clk(int dev_index)
285 struct exynos4_clock *clk =
286 (struct exynos4_clock *)samsung_get_base_clock();
287 unsigned long uclk, sclk;
300 sel = readl(&clk->src_peril0);
301 sel = (sel >> (dev_index << 2)) & 0xf;
304 sclk = get_pll_clk(MPLL);
306 sclk = get_pll_clk(EPLL);
308 sclk = get_pll_clk(VPLL);
317 * UART3_RATIO [12:15]
318 * UART4_RATIO [16:19]
319 * UART5_RATIO [23:20]
321 ratio = readl(&clk->div_peril0);
322 ratio = (ratio >> (dev_index << 2)) & 0xf;
324 uclk = sclk / (ratio + 1);
329 /* exynos5: return uart clock frequency */
330 static unsigned long exynos5_get_uart_clk(int dev_index)
332 struct exynos5_clock *clk =
333 (struct exynos5_clock *)samsung_get_base_clock();
334 unsigned long uclk, sclk;
347 sel = readl(&clk->src_peric0);
348 sel = (sel >> (dev_index << 2)) & 0xf;
351 sclk = get_pll_clk(MPLL);
353 sclk = get_pll_clk(EPLL);
355 sclk = get_pll_clk(VPLL);
364 * UART3_RATIO [12:15]
365 * UART4_RATIO [16:19]
366 * UART5_RATIO [23:20]
368 ratio = readl(&clk->div_peric0);
369 ratio = (ratio >> (dev_index << 2)) & 0xf;
371 uclk = sclk / (ratio + 1);
376 /* exynos4: set the mmc clock */
377 static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
379 struct exynos4_clock *clk =
380 (struct exynos4_clock *)samsung_get_base_clock();
386 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
388 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
391 addr = (unsigned int)&clk->div_fsys1;
393 addr = (unsigned int)&clk->div_fsys2;
398 val &= ~(0xff << ((dev_index << 4) + 8));
399 val |= (div & 0xff) << ((dev_index << 4) + 8);
403 /* exynos5: set the mmc clock */
404 static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
406 struct exynos5_clock *clk =
407 (struct exynos5_clock *)samsung_get_base_clock();
413 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
415 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
418 addr = (unsigned int)&clk->div_fsys1;
420 addr = (unsigned int)&clk->div_fsys2;
425 val &= ~(0xff << ((dev_index << 4) + 8));
426 val |= (div & 0xff) << ((dev_index << 4) + 8);
430 /* get_lcd_clk: return lcd clock frequency */
431 static unsigned long exynos4_get_lcd_clk(void)
433 struct exynos4_clock *clk =
434 (struct exynos4_clock *)samsung_get_base_clock();
435 unsigned long pclk, sclk;
443 sel = readl(&clk->src_lcd0);
452 sclk = get_pll_clk(MPLL);
454 sclk = get_pll_clk(EPLL);
456 sclk = get_pll_clk(VPLL);
464 ratio = readl(&clk->div_lcd0);
467 pclk = sclk / (ratio + 1);
472 /* get_lcd_clk: return lcd clock frequency */
473 static unsigned long exynos5_get_lcd_clk(void)
475 struct exynos5_clock *clk =
476 (struct exynos5_clock *)samsung_get_base_clock();
477 unsigned long pclk, sclk;
485 sel = readl(&clk->src_disp1_0);
494 sclk = get_pll_clk(MPLL);
496 sclk = get_pll_clk(EPLL);
498 sclk = get_pll_clk(VPLL);
506 ratio = readl(&clk->div_disp1_0);
509 pclk = sclk / (ratio + 1);
514 void exynos4_set_lcd_clk(void)
516 struct exynos4_clock *clk =
517 (struct exynos4_clock *)samsung_get_base_clock();
518 unsigned int cfg = 0;
530 cfg = readl(&clk->gate_block);
532 writel(cfg, &clk->gate_block);
538 * MDNIE_PWM0_SEL [8:11]
540 * set lcd0 src clock 0x6: SCLK_MPLL
542 cfg = readl(&clk->src_lcd0);
545 writel(cfg, &clk->src_lcd0);
555 * Gating all clocks for FIMD0
557 cfg = readl(&clk->gate_ip_lcd0);
559 writel(cfg, &clk->gate_ip_lcd0);
565 * MDNIE_PWM0_RATIO [11:8]
566 * MDNIE_PWM_PRE_RATIO [15:12]
567 * MIPI0_RATIO [19:16]
568 * MIPI0_PRE_RATIO [23:20]
573 writel(cfg, &clk->div_lcd0);
576 void exynos5_set_lcd_clk(void)
578 struct exynos5_clock *clk =
579 (struct exynos5_clock *)samsung_get_base_clock();
580 unsigned int cfg = 0;
592 cfg = readl(&clk->gate_block);
594 writel(cfg, &clk->gate_block);
600 * MDNIE_PWM0_SEL [8:11]
602 * set lcd0 src clock 0x6: SCLK_MPLL
604 cfg = readl(&clk->src_disp1_0);
607 writel(cfg, &clk->src_disp1_0);
617 * Gating all clocks for FIMD0
619 cfg = readl(&clk->gate_ip_disp1);
621 writel(cfg, &clk->gate_ip_disp1);
627 * MDNIE_PWM0_RATIO [11:8]
628 * MDNIE_PWM_PRE_RATIO [15:12]
629 * MIPI0_RATIO [19:16]
630 * MIPI0_PRE_RATIO [23:20]
635 writel(cfg, &clk->div_disp1_0);
638 void exynos4_set_mipi_clk(void)
640 struct exynos4_clock *clk =
641 (struct exynos4_clock *)samsung_get_base_clock();
642 unsigned int cfg = 0;
648 * MDNIE_PWM0_SEL [8:11]
650 * set mipi0 src clock 0x6: SCLK_MPLL
652 cfg = readl(&clk->src_lcd0);
655 writel(cfg, &clk->src_lcd0);
661 * MDNIE_PWM0_MASK [8]
663 * set src mask mipi0 0x1: Unmask
665 cfg = readl(&clk->src_mask_lcd0);
667 writel(cfg, &clk->src_mask_lcd0);
677 * Gating all clocks for MIPI0
679 cfg = readl(&clk->gate_ip_lcd0);
681 writel(cfg, &clk->gate_ip_lcd0);
687 * MDNIE_PWM0_RATIO [11:8]
688 * MDNIE_PWM_PRE_RATIO [15:12]
689 * MIPI0_RATIO [19:16]
690 * MIPI0_PRE_RATIO [23:20]
695 writel(cfg, &clk->div_lcd0);
701 * exynos5: obtaining the I2C clock
703 static unsigned long exynos5_get_i2c_clk(void)
705 struct exynos5_clock *clk =
706 (struct exynos5_clock *)samsung_get_base_clock();
707 unsigned long aclk_66, aclk_66_pre, sclk;
710 sclk = get_pll_clk(MPLL);
712 ratio = (readl(&clk->div_top1)) >> 24;
714 aclk_66_pre = sclk / (ratio + 1);
715 ratio = readl(&clk->div_top0);
717 aclk_66 = aclk_66_pre / (ratio + 1);
721 int exynos5_set_epll_clk(unsigned long rate)
723 unsigned int epll_con, epll_con_k;
725 unsigned int lockcnt;
727 struct exynos5_clock *clk =
728 (struct exynos5_clock *)samsung_get_base_clock();
730 epll_con = readl(&clk->epll_con0);
731 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
732 EPLL_CON0_LOCK_DET_EN_SHIFT) |
733 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
734 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
735 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
737 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
738 if (exynos5_epll_div[i].freq_out == rate)
742 if (i == ARRAY_SIZE(exynos5_epll_div))
745 epll_con_k = exynos5_epll_div[i].k_dsm << 0;
746 epll_con |= exynos5_epll_div[i].en_lock_det <<
747 EPLL_CON0_LOCK_DET_EN_SHIFT;
748 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
749 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
750 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
753 * Required period ( in cycles) to genarate a stable clock output.
754 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
755 * frequency input (as per spec)
757 lockcnt = 3000 * exynos5_epll_div[i].p_div;
759 writel(lockcnt, &clk->epll_lock);
760 writel(epll_con, &clk->epll_con0);
761 writel(epll_con_k, &clk->epll_con1);
763 start = get_timer(0);
765 while (!(readl(&clk->epll_con0) &
766 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
767 if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
768 debug("%s: Timeout waiting for EPLL lock\n", __func__);
775 void exynos5_set_i2s_clk_source(void)
777 struct exynos5_clock *clk =
778 (struct exynos5_clock *)samsung_get_base_clock();
780 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
781 (CLK_SRC_SCLK_EPLL));
784 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
785 unsigned int dst_frq)
787 struct exynos5_clock *clk =
788 (struct exynos5_clock *)samsung_get_base_clock();
791 if ((dst_frq == 0) || (src_frq == 0)) {
792 debug("%s: Invalid requency input for prescaler\n", __func__);
793 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
797 div = (src_frq / dst_frq);
798 if (div > AUDIO_1_RATIO_MASK) {
799 debug("%s: Frequency ratio is out of range\n", __func__);
800 debug("src frq = %d des frq = %d ", src_frq, dst_frq);
803 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
804 (div & AUDIO_1_RATIO_MASK));
809 * Linearly searches for the most accurate main and fine stage clock scalars
810 * (divisors) for a specified target frequency and scalar bit sizes by checking
811 * all multiples of main_scalar_bits values. Will always return scalars up to or
812 * slower than target.
814 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
815 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
816 * @param input_freq Clock frequency to be scaled in Hz
817 * @param target_freq Desired clock frequency in Hz
818 * @param best_fine_scalar Pointer to store the fine stage divisor
820 * @return best_main_scalar Main scalar for desired frequency or -1 if none
823 static int clock_calc_best_scalar(unsigned int main_scaler_bits,
824 unsigned int fine_scalar_bits, unsigned int input_rate,
825 unsigned int target_rate, unsigned int *best_fine_scalar)
828 int best_main_scalar = -1;
829 unsigned int best_error = target_rate;
830 const unsigned int cap = (1 << fine_scalar_bits) - 1;
831 const unsigned int loops = 1 << main_scaler_bits;
833 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
836 assert(best_fine_scalar != NULL);
837 assert(main_scaler_bits <= fine_scalar_bits);
839 *best_fine_scalar = 1;
841 if (input_rate == 0 || target_rate == 0)
844 if (target_rate >= input_rate)
847 for (i = 1; i <= loops; i++) {
848 const unsigned int effective_div = max(min(input_rate / i /
849 target_rate, cap), 1);
850 const unsigned int effective_rate = input_rate / i /
852 const int error = target_rate - effective_rate;
854 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
855 effective_rate, error);
857 if (error >= 0 && error <= best_error) {
859 best_main_scalar = i;
860 *best_fine_scalar = effective_div;
864 return best_main_scalar;
867 static int exynos5_set_spi_clk(enum periph_id periph_id,
870 struct exynos5_clock *clk =
871 (struct exynos5_clock *)samsung_get_base_clock();
874 unsigned shift, pre_shift;
875 unsigned mask = 0xff;
878 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
880 debug("%s: Cannot set clock rate for periph %d",
881 __func__, periph_id);
889 reg = &clk->div_peric1;
894 reg = &clk->div_peric1;
899 reg = &clk->div_peric2;
904 reg = &clk->sclk_div_isp;
909 reg = &clk->sclk_div_isp;
914 debug("%s: Unsupported peripheral ID %d\n", __func__,
918 clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
919 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
924 static unsigned long exynos4_get_i2c_clk(void)
926 struct exynos4_clock *clk =
927 (struct exynos4_clock *)samsung_get_base_clock();
928 unsigned long sclk, aclk_100;
931 sclk = get_pll_clk(APLL);
933 ratio = (readl(&clk->div_top)) >> 4;
935 aclk_100 = sclk / (ratio + 1);
939 unsigned long get_pll_clk(int pllreg)
941 if (cpu_is_exynos5())
942 return exynos5_get_pll_clk(pllreg);
944 return exynos4_get_pll_clk(pllreg);
947 unsigned long get_arm_clk(void)
949 if (cpu_is_exynos5())
950 return exynos5_get_arm_clk();
952 return exynos4_get_arm_clk();
955 unsigned long get_i2c_clk(void)
957 if (cpu_is_exynos5()) {
958 return exynos5_get_i2c_clk();
959 } else if (cpu_is_exynos4()) {
960 return exynos4_get_i2c_clk();
962 debug("I2C clock is not set for this CPU\n");
967 unsigned long get_pwm_clk(void)
969 if (cpu_is_exynos5())
970 return exynos5_get_pwm_clk();
972 return exynos4_get_pwm_clk();
975 unsigned long get_uart_clk(int dev_index)
977 if (cpu_is_exynos5())
978 return exynos5_get_uart_clk(dev_index);
980 return exynos4_get_uart_clk(dev_index);
983 void set_mmc_clk(int dev_index, unsigned int div)
985 if (cpu_is_exynos5())
986 exynos5_set_mmc_clk(dev_index, div);
988 exynos4_set_mmc_clk(dev_index, div);
991 unsigned long get_lcd_clk(void)
993 if (cpu_is_exynos4())
994 return exynos4_get_lcd_clk();
996 return exynos5_get_lcd_clk();
999 void set_lcd_clk(void)
1001 if (cpu_is_exynos4())
1002 exynos4_set_lcd_clk();
1004 exynos5_set_lcd_clk();
1007 void set_mipi_clk(void)
1009 if (cpu_is_exynos4())
1010 exynos4_set_mipi_clk();
1013 int set_spi_clk(int periph_id, unsigned int rate)
1015 if (cpu_is_exynos5())
1016 return exynos5_set_spi_clk(periph_id, rate);
1021 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
1024 if (cpu_is_exynos5())
1025 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq);
1030 void set_i2s_clk_source(void)
1032 if (cpu_is_exynos5())
1033 exynos5_set_i2s_clk_source();
1036 int set_epll_clk(unsigned long rate)
1038 if (cpu_is_exynos5())
1039 return exynos5_set_epll_clk(rate);