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 unsigned long get_pll_clk(int pllreg
)
926 if (cpu_is_exynos5())
927 return exynos5_get_pll_clk(pllreg
);
929 return exynos4_get_pll_clk(pllreg
);
932 unsigned long get_arm_clk(void)
934 if (cpu_is_exynos5())
935 return exynos5_get_arm_clk();
937 return exynos4_get_arm_clk();
940 unsigned long get_i2c_clk(void)
942 if (cpu_is_exynos5()) {
943 return exynos5_get_i2c_clk();
945 debug("I2C clock is not set for this CPU\n");
950 unsigned long get_pwm_clk(void)
952 if (cpu_is_exynos5())
953 return exynos5_get_pwm_clk();
955 return exynos4_get_pwm_clk();
958 unsigned long get_uart_clk(int dev_index
)
960 if (cpu_is_exynos5())
961 return exynos5_get_uart_clk(dev_index
);
963 return exynos4_get_uart_clk(dev_index
);
966 void set_mmc_clk(int dev_index
, unsigned int div
)
968 if (cpu_is_exynos5())
969 exynos5_set_mmc_clk(dev_index
, div
);
971 exynos4_set_mmc_clk(dev_index
, div
);
974 unsigned long get_lcd_clk(void)
976 if (cpu_is_exynos4())
977 return exynos4_get_lcd_clk();
979 return exynos5_get_lcd_clk();
982 void set_lcd_clk(void)
984 if (cpu_is_exynos4())
985 exynos4_set_lcd_clk();
987 exynos5_set_lcd_clk();
990 void set_mipi_clk(void)
992 if (cpu_is_exynos4())
993 exynos4_set_mipi_clk();
996 int set_spi_clk(int periph_id
, unsigned int rate
)
998 if (cpu_is_exynos5())
999 return exynos5_set_spi_clk(periph_id
, rate
);
1004 int set_i2s_clk_prescaler(unsigned int src_frq
, unsigned int dst_frq
)
1007 if (cpu_is_exynos5())
1008 return exynos5_set_i2s_clk_prescaler(src_frq
, dst_frq
);
1013 void set_i2s_clk_source(void)
1015 if (cpu_is_exynos5())
1016 exynos5_set_i2s_clk_source();
1019 int set_epll_clk(unsigned long rate
)
1021 if (cpu_is_exynos5())
1022 return exynos5_set_epll_clk(rate
);