1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
5 #include <console/console.h>
7 #include <soc/periph.h>
10 /* input clock of PLL: SMDK5420 has 24MHz input clock */
11 #define CONF_SYS_CLK_FREQ 24000000
13 /* Epll Clock division values to achieve different frequency output */
14 static struct st_epll_con_val epll_div
[] = {
15 { 192000000, 0, 48, 3, 1, 0 },
16 { 180000000, 0, 45, 3, 1, 0 },
17 { 73728000, 1, 73, 3, 3, 47710 },
18 { 67737600, 1, 90, 4, 3, 20762 },
19 { 49152000, 0, 49, 3, 3, 9961 },
20 { 45158400, 0, 45, 3, 3, 10381 },
21 { 180633600, 0, 45, 3, 1, 10381 }
24 /* exynos5: return pll clock frequency */
25 unsigned long get_pll_clk(int pllreg
)
27 unsigned long r
, m
, p
, s
, k
= 0, mask
, fout
;
32 r
= read32(&exynos_clock
->apll_con0
);
35 r
= read32(&exynos_clock
->mpll_con0
);
38 r
= read32(&exynos_clock
->epll_con0
);
39 k
= read32(&exynos_clock
->epll_con1
);
42 r
= read32(&exynos_clock
->vpll_con0
);
43 k
= read32(&exynos_clock
->vpll_con1
);
46 r
= read32(&exynos_clock
->bpll_con0
);
49 r
= read32(&exynos_clock
->rpll_con0
);
50 k
= read32(&exynos_clock
->rpll_con1
);
53 r
= read32(&exynos_clock
->spll_con0
);
56 r
= read32(&exynos_clock
->cpll_con0
);
59 r
= read32(&exynos_clock
->dpll_con0
);
62 printk(BIOS_DEBUG
, "Unsupported PLL (%d)\n", pllreg
);
67 * APLL_CON: MIDV [25:16]
68 * MPLL_CON: MIDV [25:16]
69 * EPLL_CON: MIDV [24:16]
70 * VPLL_CON: MIDV [24:16]
72 if (pllreg
== APLL
|| pllreg
== BPLL
|| pllreg
== MPLL
||
85 freq
= CONF_SYS_CLK_FREQ
;
87 if (pllreg
== EPLL
|| pllreg
== RPLL
) {
89 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
90 fout
= (m
+ k
/ 65536) * (freq
/ (p
* (1 << s
)));
91 } else if (pllreg
== VPLL
) {
93 /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
94 fout
= (m
+ k
/ 1024) * (freq
/ (p
* (1 << s
)));
96 /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
97 fout
= m
* (freq
/ (p
* (1 << s
)));
103 enum peripheral_clock_select
{
113 static int clock_select_to_pll(enum peripheral_clock_select sel
)
118 case PERIPH_SRC_CPLL
:
121 case PERIPH_SRC_DPLL
:
124 case PERIPH_SRC_MPLL
:
127 case PERIPH_SRC_SPLL
:
130 case PERIPH_SRC_IPLL
:
133 case PERIPH_SRC_EPLL
:
136 case PERIPH_SRC_RPLL
:
147 unsigned long clock_get_periph_rate(enum periph_id peripheral
)
153 switch (peripheral
) {
154 case PERIPH_ID_UART0
:
155 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 4) & 0x7;
156 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 8) & 0xf;
158 case PERIPH_ID_UART1
:
159 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 8) & 0x7;
160 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 12) & 0xf;
162 case PERIPH_ID_UART2
:
163 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 12) & 0x7;
164 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 16) & 0xf;
166 case PERIPH_ID_UART3
:
167 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 16) & 0x7;
168 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 20) & 0xf;
175 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 24) & 0x7;
176 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 28) & 0x7;
179 src
= (read32(&exynos_clock
->clk_src_peric1
) >> 20) & 0x7;
180 div
= (read32(&exynos_clock
->clk_div_peric1
) >> 20) & 0xf;
183 src
= (read32(&exynos_clock
->clk_src_peric1
) >> 24) & 0x7;
184 div
= (read32(&exynos_clock
->clk_div_peric1
) >> 24) & 0xf;
187 src
= (read32(&exynos_clock
->clk_src_peric1
) >> 28) & 0x7;
188 div
= (read32(&exynos_clock
->clk_div_peric1
) >> 28) & 0xf;
190 case PERIPH_ID_SPI3
: /* aka SPI0_ISP */
191 src
= (read32(&exynos_clock
->clk_src_isp
) >> 16) & 0x7;
192 div
= (read32(&exynos_clock
->clk_div_isp0
) >> 0) & 0x7;
194 case PERIPH_ID_SPI4
: /* aka SPI1_ISP */
195 src
= (read32(&exynos_clock
->clk_src_isp
) >> 12) & 0x7;
196 div
= (read32(&exynos_clock
->clk_div_isp1
) >> 4) & 0x7;
208 case PERIPH_ID_I2C10
:
210 * I2C block parent clock selection is different from other
211 * peripherals, so we handle it all here.
212 * TODO: Add a helper function like with the peripheral clock
215 src
= (read32(&exynos_clock
->clk_src_top1
) >> 8) & 0x3;
225 sclk
= get_pll_clk(src
);
226 div
= ((read32(&exynos_clock
->clk_div_top1
) >> 8) & 0x3f) + 1;
229 printk(BIOS_DEBUG
, "%s: invalid peripheral %d",
230 __func__
, peripheral
);
234 src
= clock_select_to_pll(src
);
236 printk(BIOS_DEBUG
, "%s: cannot determine source PLL", __func__
);
240 sclk
= get_pll_clk(src
);
242 return sclk
/ (div
+ 1);
245 /* exynos5: return ARM clock frequency */
246 unsigned long get_arm_clk(void)
249 unsigned long armclk
;
250 unsigned int arm_ratio
;
251 unsigned int arm2_ratio
;
253 div
= read32(&exynos_clock
->clk_div_cpu0
);
255 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
256 arm_ratio
= (div
>> 0) & 0x7;
257 arm2_ratio
= (div
>> 28) & 0x7;
259 armclk
= get_pll_clk(APLL
) / (arm_ratio
+ 1);
260 armclk
/= (arm2_ratio
+ 1);
265 /* exynos5: get the mmc clock */
266 static unsigned long get_mmc_clk(int dev_index
)
268 unsigned long uclk
, sclk
;
269 unsigned int sel
, ratio
;
272 sel
= read32(&exynos_clock
->clk_src_fsys
);
273 sel
= (sel
>> ((dev_index
* 4) + 8)) & 0x7;
276 sclk
= get_pll_clk(MPLL
);
278 sclk
= get_pll_clk(EPLL
);
282 ratio
= read32(&exynos_clock
->clk_div_fsys1
);
284 shift
= dev_index
* 10;
286 ratio
= (ratio
>> shift
) & 0x3ff;
287 uclk
= (sclk
/ (ratio
+ 1));
288 printk(BIOS_DEBUG
, "%s(%d): %lu\n", __func__
, dev_index
, uclk
);
293 /* exynos5: set the mmc clock */
294 void set_mmc_clk(int dev_index
, unsigned int div
)
297 unsigned int val
, shift
;
299 addr
= &exynos_clock
->clk_div_fsys1
;
300 shift
= dev_index
* 10;
303 val
&= ~(0x3ff << shift
);
304 val
|= (div
& 0x3ff) << shift
;
308 /* Set DW MMC Controller clock */
309 int clock_set_dwmci(enum periph_id peripheral
)
311 /* Request MMC clock value to 52MHz. */
312 const unsigned long freq
= 52000000;
313 unsigned long sdclkin
, cclkin
;
314 int device_index
= (int)peripheral
- (int)PERIPH_ID_SDMMC0
;
316 ASSERT(device_index
>= 0 && device_index
< 4);
317 sdclkin
= get_mmc_clk(device_index
);
322 /* The SDCLKIN is divided inside the controller by the DIVRATIO field in
323 * CLKSEL register, so we must calculate clock value as
324 * cclk_in = SDCLKIN / (DIVRATIO + 1)
325 * Currently the RIVRATIO must be 3 for MMC0 and MMC2 on Exynos5420
326 * (and must be configured in payload).
328 if (device_index
== 0 || device_index
== 2){
330 sdclkin
/= (divratio
+ 1);
332 printk(BIOS_DEBUG
, "%s(%d): sdclkin: %ld\n", __func__
, device_index
, sdclkin
);
334 cclkin
= DIV_ROUND_UP(sdclkin
, freq
);
335 set_mmc_clk(device_index
, cclkin
);
339 void clock_ll_set_pre_ratio(enum periph_id periph_id
, unsigned int divisor
)
342 unsigned int mask
= 0xff;
346 * For now we only handle a very small subset of peripherals here.
347 * Others will need to (and do) mangle the clock registers
348 * themselves, At some point it is hoped that this function can work
349 * from a table or calculated register offset / mask. For now this
350 * is at least better than spreading clock control code around
355 reg
= &exynos_clock
->clk_div_peric4
;
359 reg
= &exynos_clock
->clk_div_peric4
;
363 reg
= &exynos_clock
->clk_div_peric4
;
367 reg
= &exynos_clock
->clk_div_isp1
;
371 reg
= &exynos_clock
->clk_div_isp1
;
375 printk(BIOS_DEBUG
, "%s: Unsupported peripheral ID %d\n", __func__
,
379 clrsetbits32(reg
, mask
<< shift
, (divisor
& mask
) << shift
);
382 void clock_ll_set_ratio(enum periph_id periph_id
, unsigned int divisor
)
385 unsigned int mask
= 0xf;
390 reg
= &exynos_clock
->clk_div_peric1
;
394 reg
= &exynos_clock
->clk_div_peric1
;
398 reg
= &exynos_clock
->clk_div_peric1
;
402 reg
= &exynos_clock
->clk_div_isp1
;
406 reg
= &exynos_clock
->clk_div_isp1
;
410 printk(BIOS_DEBUG
, "%s: Unsupported peripheral ID %d\n", __func__
,
414 clrsetbits32(reg
, mask
<< shift
, (divisor
& mask
) << shift
);
418 * Linearly searches for the most accurate main and fine stage clock scalars
419 * (divisors) for a specified target frequency and scalar bit sizes by checking
420 * all multiples of main_scalar_bits values. Will always return scalars up to or
421 * slower than target.
423 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
424 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
425 * @param input_rate Clock frequency to be scaled in Hz
426 * @param target_rate Desired clock frequency in Hz
427 * @param best_fine_scalar Pointer to store the fine stage divisor
429 * @return best_main_scalar Main scalar for desired frequency or -1 if none
432 static int clock_calc_best_scalar(unsigned int main_scaler_bits
,
433 unsigned int fine_scalar_bits
, unsigned int input_rate
,
434 unsigned int target_rate
, unsigned int *best_fine_scalar
)
437 int best_main_scalar
= -1;
438 unsigned int best_error
= target_rate
;
439 const unsigned int cap
= (1 << fine_scalar_bits
) - 1;
440 const unsigned int loops
= 1 << main_scaler_bits
;
442 printk(BIOS_DEBUG
, "Input Rate is %u, Target is %u, Cap is %u\n", input_rate
,
445 ASSERT(best_fine_scalar
!= NULL
);
446 ASSERT(main_scaler_bits
<= fine_scalar_bits
);
448 *best_fine_scalar
= 1;
450 if (input_rate
== 0 || target_rate
== 0)
453 if (target_rate
>= input_rate
)
456 for (i
= 1; i
<= loops
; i
++) {
457 const unsigned int effective_div
= MAX(MIN(input_rate
/ i
/
458 target_rate
, cap
), 1);
459 const unsigned int effective_rate
= input_rate
/ i
/
461 const int error
= target_rate
- effective_rate
;
463 printk(BIOS_DEBUG
, "%d|effdiv:%u, effrate:%u, error:%d\n", i
, effective_div
,
464 effective_rate
, error
);
466 if (error
>= 0 && error
<= best_error
) {
468 best_main_scalar
= i
;
469 *best_fine_scalar
= effective_div
;
473 return best_main_scalar
;
476 int clock_set_rate(enum periph_id periph_id
, unsigned int rate
)
487 main_scalar
= clock_calc_best_scalar(4, 8, 400000000, rate
, &fine
);
488 if (main_scalar
< 0) {
489 printk(BIOS_DEBUG
, "%s: Cannot set clock rate for periph %d",
490 __func__
, periph_id
);
493 clock_ll_set_ratio(periph_id
, main_scalar
- 1);
494 clock_ll_set_pre_ratio(periph_id
, fine
- 1);
497 printk(BIOS_DEBUG
, "%s: Unsupported peripheral ID %d\n", __func__
,
505 int clock_set_mshci(enum periph_id peripheral
)
513 clock
= get_pll_clk(MPLL
) / 1000000;
517 * MMC0_PRE_RATIO [15:8], MMC0_RATIO [3:0]
519 * MMC2_PRE_RATIO [15:8], MMC2_RATIO [3:0]
521 switch (peripheral
) {
522 case PERIPH_ID_SDMMC0
:
523 addr
= &exynos_clock
->clk_div_fsys1
;
525 case PERIPH_ID_SDMMC2
:
526 addr
= &exynos_clock
->clk_div_fsys2
;
529 printk(BIOS_DEBUG
, "invalid peripheral\n");
532 tmp
= read32(addr
) & ~0xff0f;
533 for (i
= 0; i
<= 0xf; i
++) {
534 if ((clock
/ (i
+ 1)) <= 400) {
535 write32(addr
, tmp
| i
<< 0);
542 int clock_epll_set_rate(unsigned long rate
)
544 unsigned int epll_con
, epll_con_k
;
546 unsigned int lockcnt
;
549 epll_con
= read32(&exynos_clock
->epll_con0
);
550 epll_con
&= ~((EPLL_CON0_LOCK_DET_EN_MASK
<<
551 EPLL_CON0_LOCK_DET_EN_SHIFT
) |
552 EPLL_CON0_MDIV_MASK
<< EPLL_CON0_MDIV_SHIFT
|
553 EPLL_CON0_PDIV_MASK
<< EPLL_CON0_PDIV_SHIFT
|
554 EPLL_CON0_SDIV_MASK
<< EPLL_CON0_SDIV_SHIFT
);
556 for (i
= 0; i
< ARRAY_SIZE(epll_div
); i
++) {
557 if (epll_div
[i
].freq_out
== rate
)
561 if (i
== ARRAY_SIZE(epll_div
))
564 epll_con_k
= epll_div
[i
].k_dsm
<< 0;
565 epll_con
|= epll_div
[i
].en_lock_det
<< EPLL_CON0_LOCK_DET_EN_SHIFT
;
566 epll_con
|= epll_div
[i
].m_div
<< EPLL_CON0_MDIV_SHIFT
;
567 epll_con
|= epll_div
[i
].p_div
<< EPLL_CON0_PDIV_SHIFT
;
568 epll_con
|= epll_div
[i
].s_div
<< EPLL_CON0_SDIV_SHIFT
;
571 * Required period (in cycles) to generate a stable clock output.
572 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
573 * frequency input (as per spec)
575 lockcnt
= 3000 * epll_div
[i
].p_div
;
577 write32(&exynos_clock
->epll_lock
, lockcnt
);
578 write32(&exynos_clock
->epll_con0
, epll_con
);
579 write32(&exynos_clock
->epll_con1
, epll_con_k
);
581 stopwatch_init_msecs_expire(&sw
, TIMEOUT_EPLL_LOCK
);
583 while (!(read32(&exynos_clock
->epll_con0
) &
584 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT
))) {
585 if (stopwatch_expired(&sw
)) {
586 printk(BIOS_DEBUG
, "%s: Timeout waiting for EPLL lock\n", __func__
);
594 void clock_select_i2s_clk_source(void)
596 clrsetbits32(&exynos_clock
->clk_src_peric1
, AUDIO1_SEL_MASK
,
597 (CLK_SRC_SCLK_EPLL
));
600 int clock_set_i2s_clk_prescaler(unsigned int src_frq
, unsigned int dst_frq
)
604 if ((dst_frq
== 0) || (src_frq
== 0)) {
605 printk(BIOS_DEBUG
, "%s: Invalid frequency input for prescaler\n", __func__
);
606 printk(BIOS_DEBUG
, "src frq = %d des frq = %d ", src_frq
, dst_frq
);
610 div
= (src_frq
/ dst_frq
);
611 if (div
> AUDIO_1_RATIO_MASK
) {
612 printk(BIOS_DEBUG
, "%s: Frequency ratio is out of range\n", __func__
);
613 printk(BIOS_DEBUG
, "src frq = %d des frq = %d ", src_frq
, dst_frq
);
616 clrsetbits32(&exynos_clock
->clk_div_peric4
, AUDIO_1_RATIO_MASK
,
617 (div
& AUDIO_1_RATIO_MASK
));