2 * This file is part of the coreboot project.
4 * Copyright (C) 2010 Samsung Electronics
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
18 #include <console/console.h>
20 #include <soc/periph.h>
24 /* input clock of PLL: SMDK5420 has 24MHz input clock */
25 #define CONFIG_SYS_CLK_FREQ 24000000
27 /* Epll Clock division values to achieve different frequency output */
28 static struct st_epll_con_val epll_div
[] = {
29 { 192000000, 0, 48, 3, 1, 0 },
30 { 180000000, 0, 45, 3, 1, 0 },
31 { 73728000, 1, 73, 3, 3, 47710 },
32 { 67737600, 1, 90, 4, 3, 20762 },
33 { 49152000, 0, 49, 3, 3, 9961 },
34 { 45158400, 0, 45, 3, 3, 10381 },
35 { 180633600, 0, 45, 3, 1, 10381 }
38 /* exynos5: return pll clock frequency */
39 unsigned long get_pll_clk(int pllreg
)
41 unsigned long r
, m
, p
, s
, k
= 0, mask
, fout
;
46 r
= read32(&exynos_clock
->apll_con0
);
49 r
= read32(&exynos_clock
->mpll_con0
);
52 r
= read32(&exynos_clock
->epll_con0
);
53 k
= read32(&exynos_clock
->epll_con1
);
56 r
= read32(&exynos_clock
->vpll_con0
);
57 k
= read32(&exynos_clock
->vpll_con1
);
60 r
= read32(&exynos_clock
->bpll_con0
);
63 r
= read32(&exynos_clock
->rpll_con0
);
64 k
= read32(&exynos_clock
->rpll_con1
);
67 r
= read32(&exynos_clock
->spll_con0
);
70 r
= read32(&exynos_clock
->cpll_con0
);
73 r
= read32(&exynos_clock
->dpll_con0
);
76 printk(BIOS_DEBUG
, "Unsupported PLL (%d)\n", pllreg
);
81 * APLL_CON: MIDV [25:16]
82 * MPLL_CON: MIDV [25:16]
83 * EPLL_CON: MIDV [24:16]
84 * VPLL_CON: MIDV [24:16]
86 if (pllreg
== APLL
|| pllreg
== BPLL
|| pllreg
== MPLL
||
99 freq
= CONFIG_SYS_CLK_FREQ
;
101 if (pllreg
== EPLL
|| pllreg
== RPLL
) {
103 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
104 fout
= (m
+ k
/ 65536) * (freq
/ (p
* (1 << s
)));
105 } else if (pllreg
== VPLL
) {
107 /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
108 fout
= (m
+ k
/ 1024) * (freq
/ (p
* (1 << s
)));
110 /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
111 fout
= m
* (freq
/ (p
* (1 << s
)));
117 enum peripheral_clock_select
{
127 static int clock_select_to_pll(enum peripheral_clock_select sel
)
132 case PERIPH_SRC_CPLL
:
135 case PERIPH_SRC_DPLL
:
138 case PERIPH_SRC_MPLL
:
141 case PERIPH_SRC_SPLL
:
144 case PERIPH_SRC_IPLL
:
147 case PERIPH_SRC_EPLL
:
150 case PERIPH_SRC_RPLL
:
161 unsigned long clock_get_periph_rate(enum periph_id peripheral
)
164 unsigned int src
, div
;
166 switch (peripheral
) {
167 case PERIPH_ID_UART0
:
168 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 4) & 0x7;
169 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 8) & 0xf;
171 case PERIPH_ID_UART1
:
172 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 8) & 0x7;
173 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 12) & 0xf;
175 case PERIPH_ID_UART2
:
176 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 12) & 0x7;
177 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 16) & 0xf;
179 case PERIPH_ID_UART3
:
180 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 16) & 0x7;
181 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 20) & 0xf;
188 src
= (read32(&exynos_clock
->clk_src_peric0
) >> 24) & 0x7;
189 div
= (read32(&exynos_clock
->clk_div_peric0
) >> 28) & 0x7;
192 src
= (read32(&exynos_clock
->clk_src_peric1
) >> 20) & 0x7;
193 div
= (read32(&exynos_clock
->clk_div_peric1
) >> 20) & 0xf;
196 src
= (read32(&exynos_clock
->clk_src_peric1
) >> 24) & 0x7;
197 div
= (read32(&exynos_clock
->clk_div_peric1
) >> 24) & 0xf;
200 src
= (read32(&exynos_clock
->clk_src_peric1
) >> 28) & 0x7;
201 div
= (read32(&exynos_clock
->clk_div_peric1
) >> 28) & 0xf;
203 case PERIPH_ID_SPI3
: /* aka SPI0_ISP */
204 src
= (read32(&exynos_clock
->clk_src_isp
) >> 16) & 0x7;
205 div
= (read32(&exynos_clock
->clk_div_isp0
) >> 0) & 0x7;
207 case PERIPH_ID_SPI4
: /* aka SPI1_ISP */
208 src
= (read32(&exynos_clock
->clk_src_isp
) >> 12) & 0x7;
209 div
= (read32(&exynos_clock
->clk_div_isp1
) >> 4) & 0x7;
221 case PERIPH_ID_I2C10
:
223 * I2C block parent clock selection is different from other
224 * peripherals, so we handle it all here.
225 * TODO: Add a helper function like with the peripheral clock
228 src
= (read32(&exynos_clock
->clk_src_top1
) >> 8) & 0x3;
238 sclk
= get_pll_clk(src
);
239 div
= ((read32(&exynos_clock
->clk_div_top1
) >> 8) & 0x3f) + 1;
242 printk(BIOS_DEBUG
, "%s: invalid peripheral %d",
243 __func__
, peripheral
);
247 src
= clock_select_to_pll(src
);
249 printk(BIOS_DEBUG
, "%s: cannot determine source PLL", __func__
);
253 sclk
= get_pll_clk(src
);
255 return sclk
/ (div
+ 1);
258 /* exynos5: return ARM clock frequency */
259 unsigned long get_arm_clk(void)
262 unsigned long armclk
;
263 unsigned int arm_ratio
;
264 unsigned int arm2_ratio
;
266 div
= read32(&exynos_clock
->clk_div_cpu0
);
268 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
269 arm_ratio
= (div
>> 0) & 0x7;
270 arm2_ratio
= (div
>> 28) & 0x7;
272 armclk
= get_pll_clk(APLL
) / (arm_ratio
+ 1);
273 armclk
/= (arm2_ratio
+ 1);
278 /* exynos5: get the mmc clock */
279 static unsigned long get_mmc_clk(int dev_index
)
281 unsigned long uclk
, sclk
;
282 unsigned int sel
, ratio
;
285 sel
= read32(&exynos_clock
->clk_src_fsys
);
286 sel
= (sel
>> ((dev_index
* 4) + 8)) & 0x7;
289 sclk
= get_pll_clk(MPLL
);
291 sclk
= get_pll_clk(EPLL
);
295 ratio
= read32(&exynos_clock
->clk_div_fsys1
);
297 shift
= dev_index
* 10;
299 ratio
= (ratio
>> shift
) & 0x3ff;
300 uclk
= (sclk
/ (ratio
+ 1));
301 printk(BIOS_DEBUG
, "%s(%d): %lu\n", __func__
, dev_index
, uclk
);
306 /* exynos5: set the mmc clock */
307 void set_mmc_clk(int dev_index
, unsigned int div
)
310 unsigned int val
, shift
;
312 addr
= &exynos_clock
->clk_div_fsys1
;
313 shift
= dev_index
* 10;
316 val
&= ~(0x3ff << shift
);
317 val
|= (div
& 0x3ff) << shift
;
321 /* Set DW MMC Controller clock */
322 int clock_set_dwmci(enum periph_id peripheral
)
324 /* Request MMC clock value to 52MHz. */
325 const unsigned long freq
= 52000000;
326 unsigned long sdclkin
, cclkin
;
327 int device_index
= (int)peripheral
- (int)PERIPH_ID_SDMMC0
;
329 ASSERT(device_index
>= 0 && device_index
< 4);
330 sdclkin
= get_mmc_clk(device_index
);
335 /* The SDCLKIN is divided inside the controller by the DIVRATIO field in
336 * CLKSEL register, so we must calculate clock value as
337 * cclk_in = SDCLKIN / (DIVRATIO + 1)
338 * Currently the RIVRATIO must be 3 for MMC0 and MMC2 on Exynos5420
339 * (and must be configured in payload).
341 if (device_index
== 0 || device_index
== 2){
343 sdclkin
/= (divratio
+ 1);
345 printk(BIOS_DEBUG
, "%s(%d): sdclkin: %ld\n", __func__
, device_index
, sdclkin
);
347 cclkin
= CEIL_DIV(sdclkin
, freq
);
348 set_mmc_clk(device_index
, cclkin
);
352 void clock_ll_set_pre_ratio(enum periph_id periph_id
, unsigned divisor
)
355 unsigned mask
= 0xff;
359 * For now we only handle a very small subset of peripherals here.
360 * Others will need to (and do) mangle the clock registers
361 * themselves, At some point it is hoped that this function can work
362 * from a table or calculated register offset / mask. For now this
363 * is at least better than spreading clock control code around
368 reg
= &exynos_clock
->clk_div_peric4
;
372 reg
= &exynos_clock
->clk_div_peric4
;
376 reg
= &exynos_clock
->clk_div_peric4
;
380 reg
= &exynos_clock
->clk_div_isp1
;
384 reg
= &exynos_clock
->clk_div_isp1
;
388 printk(BIOS_DEBUG
, "%s: Unsupported peripheral ID %d\n", __func__
,
392 clrsetbits_le32(reg
, mask
<< shift
, (divisor
& mask
) << shift
);
395 void clock_ll_set_ratio(enum periph_id periph_id
, unsigned divisor
)
403 reg
= &exynos_clock
->clk_div_peric1
;
407 reg
= &exynos_clock
->clk_div_peric1
;
411 reg
= &exynos_clock
->clk_div_peric1
;
415 reg
= &exynos_clock
->clk_div_isp1
;
419 reg
= &exynos_clock
->clk_div_isp1
;
423 printk(BIOS_DEBUG
, "%s: Unsupported peripheral ID %d\n", __func__
,
427 clrsetbits_le32(reg
, mask
<< shift
, (divisor
& mask
) << shift
);
431 * Linearly searches for the most accurate main and fine stage clock scalars
432 * (divisors) for a specified target frequency and scalar bit sizes by checking
433 * all multiples of main_scalar_bits values. Will always return scalars up to or
434 * slower than target.
436 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
437 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
438 * @param input_rate Clock frequency to be scaled in Hz
439 * @param target_rate Desired clock frequency in Hz
440 * @param best_fine_scalar Pointer to store the fine stage divisor
442 * @return best_main_scalar Main scalar for desired frequency or -1 if none
445 static int clock_calc_best_scalar(unsigned int main_scaler_bits
,
446 unsigned int fine_scalar_bits
, unsigned int input_rate
,
447 unsigned int target_rate
, unsigned int *best_fine_scalar
)
450 int best_main_scalar
= -1;
451 unsigned int best_error
= target_rate
;
452 const unsigned int cap
= (1 << fine_scalar_bits
) - 1;
453 const unsigned int loops
= 1 << main_scaler_bits
;
455 printk(BIOS_DEBUG
, "Input Rate is %u, Target is %u, Cap is %u\n", input_rate
,
458 ASSERT(best_fine_scalar
!= NULL
);
459 ASSERT(main_scaler_bits
<= fine_scalar_bits
);
461 *best_fine_scalar
= 1;
463 if (input_rate
== 0 || target_rate
== 0)
466 if (target_rate
>= input_rate
)
469 for (i
= 1; i
<= loops
; i
++) {
470 const unsigned int effective_div
= MAX(MIN(input_rate
/ i
/
471 target_rate
, cap
), 1);
472 const unsigned int effective_rate
= input_rate
/ i
/
474 const int error
= target_rate
- effective_rate
;
476 printk(BIOS_DEBUG
, "%d|effdiv:%u, effrate:%u, error:%d\n", i
, effective_div
,
477 effective_rate
, error
);
479 if (error
>= 0 && error
<= best_error
) {
481 best_main_scalar
= i
;
482 *best_fine_scalar
= effective_div
;
486 return best_main_scalar
;
489 int clock_set_rate(enum periph_id periph_id
, unsigned int rate
)
500 main_scalar
= clock_calc_best_scalar(4, 8, 400000000, rate
, &fine
);
501 if (main_scalar
< 0) {
502 printk(BIOS_DEBUG
, "%s: Cannot set clock rate for periph %d",
503 __func__
, periph_id
);
506 clock_ll_set_ratio(periph_id
, main_scalar
- 1);
507 clock_ll_set_pre_ratio(periph_id
, fine
- 1);
510 printk(BIOS_DEBUG
, "%s: Unsupported peripheral ID %d\n", __func__
,
518 int clock_set_mshci(enum periph_id peripheral
)
526 clock
= get_pll_clk(MPLL
) / 1000000;
530 * MMC0_PRE_RATIO [15:8], MMC0_RATIO [3:0]
532 * MMC2_PRE_RATIO [15:8], MMC2_RATIO [3:0]
534 switch (peripheral
) {
535 case PERIPH_ID_SDMMC0
:
536 addr
= &exynos_clock
->clk_div_fsys1
;
538 case PERIPH_ID_SDMMC2
:
539 addr
= &exynos_clock
->clk_div_fsys2
;
542 printk(BIOS_DEBUG
, "invalid peripheral\n");
545 tmp
= read32(addr
) & ~0xff0f;
546 for (i
= 0; i
<= 0xf; i
++) {
547 if ((clock
/ (i
+ 1)) <= 400) {
548 write32(addr
, tmp
| i
<< 0);
555 int clock_epll_set_rate(unsigned long rate
)
557 unsigned int epll_con
, epll_con_k
;
559 unsigned int lockcnt
;
562 epll_con
= read32(&exynos_clock
->epll_con0
);
563 epll_con
&= ~((EPLL_CON0_LOCK_DET_EN_MASK
<<
564 EPLL_CON0_LOCK_DET_EN_SHIFT
) |
565 EPLL_CON0_MDIV_MASK
<< EPLL_CON0_MDIV_SHIFT
|
566 EPLL_CON0_PDIV_MASK
<< EPLL_CON0_PDIV_SHIFT
|
567 EPLL_CON0_SDIV_MASK
<< EPLL_CON0_SDIV_SHIFT
);
569 for (i
= 0; i
< ARRAY_SIZE(epll_div
); i
++) {
570 if (epll_div
[i
].freq_out
== rate
)
574 if (i
== ARRAY_SIZE(epll_div
))
577 epll_con_k
= epll_div
[i
].k_dsm
<< 0;
578 epll_con
|= epll_div
[i
].en_lock_det
<< EPLL_CON0_LOCK_DET_EN_SHIFT
;
579 epll_con
|= epll_div
[i
].m_div
<< EPLL_CON0_MDIV_SHIFT
;
580 epll_con
|= epll_div
[i
].p_div
<< EPLL_CON0_PDIV_SHIFT
;
581 epll_con
|= epll_div
[i
].s_div
<< EPLL_CON0_SDIV_SHIFT
;
584 * Required period ( in cycles) to generate a stable clock output.
585 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
586 * frequency input (as per spec)
588 lockcnt
= 3000 * epll_div
[i
].p_div
;
590 write32(&exynos_clock
->epll_lock
, lockcnt
);
591 write32(&exynos_clock
->epll_con0
, epll_con
);
592 write32(&exynos_clock
->epll_con1
, epll_con_k
);
594 stopwatch_init_msecs_expire(&sw
, TIMEOUT_EPLL_LOCK
);
596 while (!(read32(&exynos_clock
->epll_con0
) &
597 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT
))) {
598 if (stopwatch_expired(&sw
)) {
599 printk(BIOS_DEBUG
, "%s: Timeout waiting for EPLL lock\n", __func__
);
607 void clock_select_i2s_clk_source(void)
609 clrsetbits_le32(&exynos_clock
->clk_src_peric1
, AUDIO1_SEL_MASK
,
610 (CLK_SRC_SCLK_EPLL
));
613 int clock_set_i2s_clk_prescaler(unsigned int src_frq
, unsigned int dst_frq
)
617 if ((dst_frq
== 0) || (src_frq
== 0)) {
618 printk(BIOS_DEBUG
, "%s: Invalid frequency input for prescaler\n", __func__
);
619 printk(BIOS_DEBUG
, "src frq = %d des frq = %d ", src_frq
, dst_frq
);
623 div
= (src_frq
/ dst_frq
);
624 if (div
> AUDIO_1_RATIO_MASK
) {
625 printk(BIOS_DEBUG
, "%s: Frequency ratio is out of range\n", __func__
);
626 printk(BIOS_DEBUG
, "src frq = %d des frq = %d ", src_frq
, dst_frq
);
629 clrsetbits_le32(&exynos_clock
->clk_div_peric4
, AUDIO_1_RATIO_MASK
,
630 (div
& AUDIO_1_RATIO_MASK
));