[U-Boot] [PATCH 3/9 V9] Exynos5420: Add clock initialization for 5420
Minkyu Kang
mk7.kang at samsung.com
Tue Dec 3 07:14:27 CET 2013
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 at samsung.com>
> Signed-off-by: Akshay Saraswat <akshay.s at samsung.com>
> Acked-by: Simon Glass <sjg at 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 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.
More information about the U-Boot
mailing list