
Dear Rajeshwari S Shinde,
On 02/12/13 20:47, Rajeshwari S Shinde wrote:
This patch adds code for clock initialization and clock settings of various IP's and controllers, required for Exynos5420
Signed-off-by: Rajeshwari S Shinde rajeshwari.s@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V2:
- None
Changes in V3:
- None
Changes in V4:
- Corrected the multiline commenting style
Changes in V5:
- None
Changes in V6:
- None
Changes in V7:
- Correct the logic for exynos5420_set_spi_clk api.
Changes in V8:
- Chnages the if condition loop for pro_id and cpu_id.
Changes in V9:
- Used samsung_get_base to get base address of clock.
arch/arm/cpu/armv7/exynos/clock.c | 258 ++++++++- arch/arm/cpu/armv7/exynos/clock_init.h | 17 + arch/arm/cpu/armv7/exynos/clock_init_exynos5.c | 352 +++++++++++- arch/arm/cpu/armv7/exynos/exynos5_setup.h | 738 +++++++++++++++++++------ arch/arm/include/asm/arch-exynos/clk.h | 1 + arch/arm/include/asm/arch-exynos/clock.h | 494 +++++++++++++++++ 6 files changed, 1659 insertions(+), 201 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 36fedd6..f2f06ac 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -96,7 +96,7 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
freq = CONFIG_SYS_CLK_FREQ;
- if (pllreg == EPLL) {
- if (pllreg == EPLL || pllreg == RPLL) { k = k & 0xffff; /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */ fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
@@ -117,7 +117,7 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k) div = PLL_DIV_1024; else if (proid_is_exynos4412()) div = PLL_DIV_65535;
else if (proid_is_exynos5250())
else return 0;else if (proid_is_exynos5250() || proid_is_exynos5420()) div = PLL_DIV_65536;
@@ -362,6 +362,43 @@ unsigned long clock_get_periph_rate(int peripheral) return 0; }
+/* exynos5420: return pll clock frequency */ +static unsigned long exynos5420_get_pll_clk(int pllreg) +{
- struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
- unsigned long r, k = 0;
- switch (pllreg) {
- case APLL:
r = readl(&clk->apll_con0);
break;
- case MPLL:
r = readl(&clk->mpll_con0);
break;
- case EPLL:
r = readl(&clk->epll_con0);
k = readl(&clk->epll_con1);
break;
- case VPLL:
r = readl(&clk->vpll_con0);
k = readl(&clk->vpll_con1);
break;
- case BPLL:
r = readl(&clk->bpll_con0);
break;
- case RPLL:
r = readl(&clk->rpll_con0);
k = readl(&clk->rpll_con1);
break;
- default:
printf("Unsupported PLL (%d)\n", pllreg);
return 0;
- }
- return exynos_get_pll_clk(pllreg, r, k);
+}
/* exynos4: return ARM clock frequency */ static unsigned long exynos4_get_arm_clk(void) { @@ -485,6 +522,27 @@ static unsigned long exynos4x12_get_pwm_clk(void) return pclk; }
+/* exynos5420: return pwm clock frequency */ +static unsigned long exynos5420_get_pwm_clk(void) +{
- struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
- unsigned long pclk, sclk;
- unsigned int ratio;
- /*
* CLK_DIV_PERIC3
peric0?
* PWM_RATIO [3:0]
then, why you right shift to 28?
*/
- ratio = readl(&clk->div_peric0);
- ratio = (ratio >> 28) & 0xf;
- sclk = get_pll_clk(MPLL);
- pclk = sclk / (ratio + 1);
- return pclk;
+}
/* exynos4: return uart clock frequency */ static unsigned long exynos4_get_uart_clk(int dev_index) { @@ -624,6 +682,53 @@ static unsigned long exynos5_get_uart_clk(int dev_index) return uclk; }
+/* exynos5420: return uart clock frequency */ +static unsigned long exynos5420_get_uart_clk(int dev_index) +{
- struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
- unsigned long uclk, sclk;
- unsigned int sel;
- unsigned int ratio;
- /*
* CLK_SRC_PERIC0
* UART0_SEL [3:0]
* UART1_SEL [7:4]
* UART2_SEL [8:11]
* UART3_SEL [12:15]
* UART4_SEL [16:19]
* UART5_SEL [23:20]
*/
- sel = readl(&clk->src_peric0);
- sel = (sel >> ((dev_index * 4) + 4)) & 0x7;
did not matched with comment and code. please check.
- if (sel == 0x3)
sclk = get_pll_clk(MPLL);
- else if (sel == 0x6)
sclk = get_pll_clk(EPLL);
- else if (sel == 0x7)
sclk = get_pll_clk(RPLL);
- else
return 0;
- /*
* CLK_DIV_PERIC0
* UART0_RATIO [3:0]
* UART1_RATIO [7:4]
* UART2_RATIO [8:11]
* UART3_RATIO [12:15]
* UART4_RATIO [16:19]
* UART5_RATIO [23:20]
*/
- ratio = readl(&clk->div_peric0);
- ratio = (ratio >> ((dev_index * 4) + 8)) & 0xf;
ditto.
- uclk = sclk / (ratio + 1);
- return uclk;
+}
static unsigned long exynos4_get_mmc_clk(int dev_index) { struct exynos4_clock *clk = @@ -718,6 +823,34 @@ static unsigned long exynos5_get_mmc_clk(int dev_index) return uclk; }
+static unsigned long exynos5420_get_mmc_clk(int dev_index) +{
- struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
- unsigned long uclk, sclk;
- unsigned int sel, ratio;
- int shift = 0;
initial value (= 0) is unnecessary.
- sel = readl(&clk->src_fsys);
- sel = (sel >> ((dev_index * 4) + 8)) & 0x7;
could you please add comment for it?
- if (sel == 0x3)
sclk = get_pll_clk(MPLL);
- else if (sel == 0x6)
sclk = get_pll_clk(EPLL);
- else
return 0;
- ratio = readl(&clk->div_fsys1);
- shift = dev_index * 10;
ditto. need comment.
- ratio = (ratio >> shift) & 0x3ff;
- uclk = (sclk / (ratio + 1));
- return uclk;
+}
/* exynos4: set the mmc clock */ static void exynos4_set_mmc_clk(int dev_index, unsigned int div) { @@ -804,6 +937,23 @@ static void exynos5_set_mmc_clk(int dev_index, unsigned int div) writel(val, addr); }
+/* exynos5: set the mmc clock */ +static void exynos5420_set_mmc_clk(int dev_index, unsigned int div) +{
- struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
- unsigned int addr;
- unsigned int val, shift;
- addr = (unsigned int)&clk->div_fsys1;
- shift = dev_index * 10;
ditto.
- val = readl(addr);
- val &= ~(0x3ff << shift);
- val |= (div & 0x3ff) << shift;
- writel(val, addr);
+}
/* get_lcd_clk: return lcd clock frequency */ static unsigned long exynos4_get_lcd_clk(void) { @@ -1324,6 +1474,72 @@ static int exynos5_set_spi_clk(enum periph_id periph_id, return 0; }
+static int exynos5420_set_spi_clk(enum periph_id periph_id,
unsigned int rate)
+{
- struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
- int main;
- unsigned int fine;
- unsigned shift, pre_shift;
- unsigned div_mask = 0xf, pre_div_mask = 0xff;
- u32 *reg;
- u32 *pre_reg;
please remove blank line.
- main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
- if (main < 0) {
debug("%s: Cannot set clock rate for periph %d",
__func__, periph_id);
return -1;
- }
- main = main - 1;
- fine = fine - 1;
- switch (periph_id) {
- case PERIPH_ID_SPI0:
reg = &clk->div_peric1;
shift = 20;
pre_reg = &clk->div_peric4;
pre_shift = 8;
break;
- case PERIPH_ID_SPI1:
reg = &clk->div_peric1;
shift = 24;
pre_reg = &clk->div_peric4;
pre_shift = 16;
break;
- case PERIPH_ID_SPI2:
reg = &clk->div_peric1;
shift = 28;
pre_reg = &clk->div_peric4;
pre_shift = 24;
break;
- case PERIPH_ID_SPI3:
reg = &clk->div_isp1;
shift = 16;
pre_reg = &clk->div_isp1;
pre_shift = 0;
break;
- case PERIPH_ID_SPI4:
reg = &clk->div_isp1;
shift = 20;
pre_reg = &clk->div_isp1;
pre_shift = 8;
break;
- default:
debug("%s: Unsupported peripheral ID %d\n", __func__,
periph_id);
return -1;
- }
- clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
- clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
(fine & pre_div_mask) << pre_shift);
- return 0;
+}
static unsigned long exynos4_get_i2c_clk(void) { struct exynos4_clock *clk = @@ -1341,9 +1557,11 @@ static unsigned long exynos4_get_i2c_clk(void)
unsigned long get_pll_clk(int pllreg) {
- if (cpu_is_exynos5())
- if (cpu_is_exynos5()) {
if (proid_is_exynos5420())
return exynos5_get_pll_clk(pllreg);return exynos5420_get_pll_clk(pllreg);
- else {
- } else { if (proid_is_exynos4412()) return exynos4x12_get_pll_clk(pllreg); return exynos4_get_pll_clk(pllreg);
@@ -1375,9 +1593,11 @@ unsigned long get_i2c_clk(void)
unsigned long get_pwm_clk(void) {
- if (cpu_is_exynos5())
- if (cpu_is_exynos5()) {
if (proid_is_exynos5420())
return clock_get_periph_rate(PERIPH_ID_PWM0);return exynos5420_get_pwm_clk();
- else {
- } else { if (proid_is_exynos4412()) return exynos4x12_get_pwm_clk(); return exynos4_get_pwm_clk();
@@ -1386,9 +1606,11 @@ unsigned long get_pwm_clk(void)
unsigned long get_uart_clk(int dev_index) {
- if (cpu_is_exynos5())
- if (cpu_is_exynos5()) {
if (proid_is_exynos5420())
return exynos5_get_uart_clk(dev_index);return exynos5420_get_uart_clk(dev_index);
- else {
- } else { if (proid_is_exynos4412()) return exynos4x12_get_uart_clk(dev_index); return exynos4_get_uart_clk(dev_index);
@@ -1397,17 +1619,22 @@ unsigned long get_uart_clk(int dev_index)
unsigned long get_mmc_clk(int dev_index) {
- if (cpu_is_exynos5())
- if (cpu_is_exynos5()) {
if (proid_is_exynos5420())
return exynos5_get_mmc_clk(dev_index);return exynos5420_get_mmc_clk(dev_index);
- else
- } else { return exynos4_get_mmc_clk(dev_index);
- }
}
void set_mmc_clk(int dev_index, unsigned int div) {
- if (cpu_is_exynos5())
- if (cpu_is_exynos5()) {
if (proid_is_exynos5420())
return exynos5420_set_mmc_clk(dev_index, div);
it's a void function. please do not return. and add else statement.
exynos5_set_mmc_clk(dev_index, div);
- else {
- } else { if (proid_is_exynos4412()) exynos4x12_set_mmc_clk(dev_index, div); exynos4_set_mmc_clk(dev_index, div);
@@ -1438,10 +1665,13 @@ void set_mipi_clk(void)
int set_spi_clk(int periph_id, unsigned int rate) {
- if (cpu_is_exynos5())
- if (cpu_is_exynos5()) {
if (proid_is_exynos5420())
return exynos5_set_spi_clk(periph_id, rate);return exynos5420_set_spi_clk(periph_id, rate);
- else
- } else { return 0;
- }
}
int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
Thanks, Minkyu Kang.