[U-Boot] [PATCH 7/9] Exynos: clock: Add generic api to get the clk freq
Simon Glass
sjg at chromium.org
Thu Feb 28 02:35:55 CET 2013
Hi Akshay,
On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s at samsung.com> wrote:
> Add generic api to get the frequency of the required peripherial. This
> API gets the source clock frequency and returns the required frequency
> by dividing with first and second dividers based on the requirement.
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
> Build and boot U-boot with this patch, backlight works properly.
Please remove the TEST= stuff. patman might do the first line for you
(and will print a warning).
>
> Signed-off-by: Padmavathi Venna <padma.v at samsung.com>
> Signed-off-by: Akshay Saraswat <akshay.s at samsung.com>
> ---
> arch/arm/cpu/armv7/exynos/clock.c | 127 +++++++++++++++++++++++++++++++++
> arch/arm/include/asm/arch-exynos/clk.h | 27 +++++++
> 2 files changed, 154 insertions(+)
>
> diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
> index 956427c..a7a3066 100644
> --- a/arch/arm/cpu/armv7/exynos/clock.c
> +++ b/arch/arm/cpu/armv7/exynos/clock.c
> @@ -27,6 +27,39 @@
> #include <asm/arch/clk.h>
> #include <asm/arch/periph.h>
>
> +/* src_bit div_bit prediv_bit */
> +static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
> + {0, 0, -1},
> + {4, 4, -1},
> + {8, 8, -1},
> + {12, 12, -1},
> + {0, 0, 8},
> + {4, 16, 24},
> + {8, 0, 8},
> + {12, 16, 24},
> + {-1, -1, -1},
> + {16, 0, 8},
> + {20, 16, 24},
> + {24, 0, 8},
> + {0, 0, 4},
> + {4, 12, 16},
> + {-1, -1, -1},
> + {-1, -1, -1},
> + {-1, 24, 0},
> + {-1, 24, 0},
> + {-1, 24, 0},
> + {-1, 24, 0},
> + {-1, 24, 0},
> + {-1, 24, 0},
> + {-1, 24, 0},
> + {-1, 24, 0},
> + {24, 0, -1},
> + {24, 0, -1},
> + {24, 0, -1},
> + {24, 0, -1},
> + {24, 0, -1},
> +};
> +
> /* Epll Clock division values to achive different frequency output */
> static struct set_epll_con_val exynos5_epll_div[] = {
> { 192000000, 0, 48, 3, 1, 0 },
> @@ -201,6 +234,100 @@ static unsigned long exynos5_get_pll_clk(int pllreg)
> return fout;
> }
>
> +unsigned long exynos5_get_periph_rate(enum periph_id peripheral)
> +{
> + struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
> + unsigned long sclk, sub_clk;
> + unsigned int src, div, sub_div;
> + struct exynos5_clock *clk =
> + (struct exynos5_clock *)samsung_get_base_clock();
> +
> + switch (peripheral) {
> + case PERIPH_ID_UART0:
> + case PERIPH_ID_UART1:
> + case PERIPH_ID_UART2:
> + case PERIPH_ID_UART3:
> + src = readl(&clk->src_peric0);
> + div = readl(&clk->div_peric0);
> + break;
> + case PERIPH_ID_PWM0:
> + case PERIPH_ID_PWM1:
> + case PERIPH_ID_PWM2:
> + case PERIPH_ID_PWM3:
> + case PERIPH_ID_PWM4:
> + src = readl(&clk->src_peric0);
> + div = readl(&clk->div_peric3);
> + break;
> + case PERIPH_ID_SPI0:
> + case PERIPH_ID_SPI1:
> + src = readl(&clk->src_peric1);
> + div = readl(&clk->div_peric1);
> + break;
> + case PERIPH_ID_SPI2:
> + src = readl(&clk->src_peric1);
> + div = readl(&clk->div_peric2);
> + break;
> + case PERIPH_ID_SPI3:
> + case PERIPH_ID_SPI4:
> + src = readl(&clk->sclk_src_isp);
> + div = readl(&clk->sclk_div_isp);
> + break;
> + case PERIPH_ID_SDMMC0:
> + case PERIPH_ID_SDMMC1:
> + case PERIPH_ID_SDMMC2:
> + case PERIPH_ID_SDMMC3:
> + src = readl(&clk->src_fsys);
> + div = readl(&clk->div_fsys1);
> + break;
> + case PERIPH_ID_I2C0:
> + case PERIPH_ID_I2C1:
> + case PERIPH_ID_I2C2:
> + case PERIPH_ID_I2C3:
> + case PERIPH_ID_I2C4:
> + case PERIPH_ID_I2C5:
> + case PERIPH_ID_I2C6:
> + case PERIPH_ID_I2C7:
> + sclk = exynos5_get_pll_clk(MPLL);
> + sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) & 0x7) + 1;
> + div = ((readl(&clk->div_top0) >> bit_info->prediv_bit) & 0x7) + 1;
> + return (sclk / sub_div) / div;
> + default:
> + debug("%s: invalid peripheral %d", __func__, peripheral);
> + return -1;
> + };
> +
> + src = (src >> bit_info->src_bit) & 0xf;
> + if (src == SRC_MPLL)
> + sclk = exynos5_get_pll_clk(MPLL);
> + else if (src == SRC_EPLL)
> + sclk = exynos5_get_pll_clk(EPLL);
> + else if (src == SRC_VPLL)
> + sclk = exynos5_get_pll_clk(VPLL);
> + else
> + return 0;
> +
> + sub_div = (div >> bit_info->div_bit) & 0xf;
> + sub_clk = sclk / (sub_div + 1);
> +
> + if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
Please can you add a comment for what this if() is doing?
> + div = (div >> bit_info->prediv_bit) & 0xff;
> + return sub_clk / (div + 1);
> + }
> +
> + return sub_clk;
> +}
> +
> +unsigned long clock_get_periph_rate(enum periph_id peripheral)
> +{
> + if (cpu_is_exynos5())
> + return exynos5_get_periph_rate(peripheral);
> + else {
> + if (proid_is_exynos4412())
> + return 0;
> + return 0;
> + }
> +}
> +
> /* exynos4: return ARM clock frequency */
> static unsigned long exynos4_get_arm_clk(void)
> {
> diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
> index 1935b0b..b459b16 100644
> --- a/arch/arm/include/asm/arch-exynos/clk.h
> +++ b/arch/arm/include/asm/arch-exynos/clk.h
> @@ -22,6 +22,8 @@
> #ifndef __ASM_ARM_ARCH_CLK_H_
> #define __ASM_ARM_ARCH_CLK_H_
>
> +#include <asm/arch/periph.h>
> +
> #define APLL 0
> #define MPLL 1
> #define EPLL 2
> @@ -29,6 +31,22 @@
> #define VPLL 4
> #define BPLL 5
Suggest EXYNOS_ prefix on these
>
> +enum pll_src_bit {
> + SRC_MPLL = 6,
> + SRC_EPLL,
> + SRC_VPLL,
> +};
> +
> +/* *
> + * This structure is to store the src bit, div bit and prediv bit
> + * positions of the peripheral clocks of the src and div registers
> + */
> +struct clk_bit_info {
> + int src_bit;
> + int div_bit;
> + int prediv_bit;
Should these perhaps be int8_t ? Can this structure move to the C file?
> +};
> +
> unsigned long get_pll_clk(int pllreg);
> unsigned long get_arm_clk(void);
> unsigned long get_i2c_clk(void);
> @@ -44,4 +62,13 @@ int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq);
> int set_epll_clk(unsigned long rate);
> int set_spi_clk(int periph_id, unsigned int rate);
>
> +/**
> + * get the clk frequency of the required peripherial
> + *
> + * @param peripherial Peripherial id
> + *
> + * @return frequency of the peripherial clk
> + */
> +unsigned long clock_get_periph_rate(enum periph_id peripheral);
> +
> #endif
> --
> 1.8.0
>
Regards,
Simon
More information about the U-Boot
mailing list