From mboxrd@z Thu Jan 1 00:00:00 1970 From: Minkyu Kang Date: Tue, 03 Dec 2013 15:14:27 +0900 Subject: [U-Boot] [PATCH 3/9 V9] Exynos5420: Add clock initialization for 5420 In-Reply-To: <1385984858-30816-4-git-send-email-rajeshwari.s@samsung.com> References: <1385984858-30816-1-git-send-email-rajeshwari.s@samsung.com> <1385984858-30816-4-git-send-email-rajeshwari.s@samsung.com> Message-ID: <529D76C3.8010908@samsung.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 > Signed-off-by: Akshay Saraswat > Acked-by: Simon Glass > --- > 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 if (proid_is_exynos5250() || proid_is_exynos5420()) > div = PLL_DIV_65536; > else > return 0; > @@ -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 exynos5420_get_pll_clk(pllreg); > return exynos5_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 exynos5420_get_pwm_clk(); > return clock_get_periph_rate(PERIPH_ID_PWM0); > - 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 exynos5420_get_uart_clk(dev_index); > return exynos5_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 exynos5420_get_mmc_clk(dev_index); > return exynos5_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 exynos5420_set_spi_clk(periph_id, rate); > return exynos5_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.