[U-Boot] [PATCH 8/9 V2] EXYNOS: Add clock for I2S
Minkyu Kang
promsoft at gmail.com
Wed Oct 17 09:49:42 CEST 2012
On 22 August 2012 15:44, Rajeshwari Shinde <rajeshwari.s at samsung.com> wrote:
> This patch adds clock support for I2S
>
> Signed-off-by: R. Chandrasekar <rcsekar at samsung.com>
> Signed-off-by: Rajeshwari Shinde <rajeshwari.s at samsung.com>
> ---
> Changes in V2:
> - None
> arch/arm/cpu/armv7/exynos/clock.c | 119 ++++++++++++++++++++++++++++++
> arch/arm/include/asm/arch-exynos/clk.h | 3 +
> arch/arm/include/asm/arch-exynos/clock.h | 29 +++++++
> 3 files changed, 151 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
> index 44dff2b..691f6d4 100644
> --- a/arch/arm/cpu/armv7/exynos/clock.c
> +++ b/arch/arm/cpu/armv7/exynos/clock.c
> @@ -26,6 +26,16 @@
> #include <asm/arch/clock.h>
> #include <asm/arch/clk.h>
>
> +/* Epll Clock division values to achive different frequency output */
> +static struct st_epll_con_val epll_div[] = {
> + { 192000000, 0, 48, 3, 1, 0 },
> + { 180000000, 0, 45, 3, 1, 0 },
> + { 73728000, 1, 73, 3, 3, 47710 },
> + { 67737600, 1, 90, 4, 3, 20762 },
> + { 49152000, 0, 49, 3, 3, 9961 },
> + { 45158400, 0, 45, 3, 3, 10381 },
> + { 180633600, 0, 45, 3, 1, 10381 }
> +};
> /* exynos4: return pll clock frequency */
> static unsigned long exynos4_get_pll_clk(int pllreg)
> {
> @@ -848,6 +858,92 @@ static int exynos5_spi_set_clock_rate(enum periph_id periph_id,
> return 0;
> }
>
> +int exynos5_clock_epll_set_rate(unsigned long rate)
exynos5_set_epll_clk
> +{
> + unsigned int epll_con, epll_con_k;
> + unsigned int i;
> + unsigned int lockcnt;
> + unsigned int start;
> + struct exynos5_clock *clk =
> + (struct exynos5_clock *)samsung_get_base_clock();
> +
> + epll_con = readl(&clk->epll_con0);
> + epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
> + EPLL_CON0_LOCK_DET_EN_SHIFT) |
> + EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
> + EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
> + EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
> +
> + for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
> + if (epll_div[i].freq_out == rate)
> + break;
> + }
> +
> + if (i == ARRAY_SIZE(epll_div))
> + return -1;
> +
> + epll_con_k = epll_div[i].k_dsm << 0;
> + epll_con |= epll_div[i].en_lock_det << EPLL_CON0_LOCK_DET_EN_SHIFT;
> + epll_con |= epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
> + epll_con |= epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
> + epll_con |= epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
> +
> + /*
> + * Required period ( in cycles) to genarate a stable clock output.
> + * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
> + * frequency input (as per spec)
> + */
> + lockcnt = 3000 * epll_div[i].p_div;
> +
> + writel(lockcnt, &clk->epll_lock);
> + writel(epll_con, &clk->epll_con0);
> + writel(epll_con_k, &clk->epll_con1);
> +
> + start = get_timer(0);
> +
> + while (!(readl(&clk->epll_con0) &
> + (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
> + if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
> + debug("%s: Timeout waiting for EPLL lock\n", __func__);
> + return -1;
> + }
> + }
> + return 0;
> +}
> +
> +void exynos5_clock_select_i2s_clk_source(void)
exynos5_set_i2s_clk_source
> +{
> + struct exynos5_clock *clk =
> + (struct exynos5_clock *)samsung_get_base_clock();
> +
> + clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
> + (CLK_SRC_SCLK_EPLL));
> +}
> +
> +int exynos5_clock_set_i2s_clk_prescaler(unsigned int src_frq,
exynos5_set_i2s_clk_prescaler
> + unsigned int dst_frq)
> +{
> + struct exynos5_clock *clk =
> + (struct exynos5_clock *)samsung_get_base_clock();
> + unsigned int div;
> +
> + if ((dst_frq == 0) || (src_frq == 0)) {
> + debug("%s: Invalid requency input for prescaler\n", __func__);
> + debug("src frq = %d des frq = %d ", src_frq, dst_frq);
> + return -1;
> + }
> +
> + div = (src_frq / dst_frq);
> + if (div > AUDIO_1_RATIO_MASK) {
> + debug("%s: Frequency ratio is out of range\n", __func__);
> + debug("src frq = %d des frq = %d ", src_frq, dst_frq);
> + return -1;
> + }
> + clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
> + (div & AUDIO_1_RATIO_MASK));
> + return 0;
> +}
> +
> unsigned long get_pll_clk(int pllreg)
> {
> if (cpu_is_exynos5())
> @@ -927,3 +1023,26 @@ int spi_set_clock_rate(enum periph_id periph_id, unsigned int rate)
> else
> return 0;
> }
> +
> +int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
set_i2s_clk_prescaler
> +{
> +
> + if (cpu_is_exynos5())
> + return exynos5_clock_set_i2s_clk_prescaler(src_frq, dst_frq);
> + else
> + return 0;
> +}
> +
> +void clock_select_i2s_clk_source(void)
set_i2s_clk_source
> +{
> + if (cpu_is_exynos5())
> + exynos5_clock_select_i2s_clk_source();
> +}
> +
> +int clock_epll_set_rate(unsigned long rate)
set_epll_clk
> +{
> + if (cpu_is_exynos5())
> + return exynos5_clock_epll_set_rate(rate);
> + else
> + return 0;
> +}
> diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
> index 4e51402..f32c634 100644
> --- a/arch/arm/include/asm/arch-exynos/clk.h
> +++ b/arch/arm/include/asm/arch-exynos/clk.h
> @@ -41,4 +41,7 @@ unsigned long get_lcd_clk(void);
> void set_lcd_clk(void);
> void set_mipi_clk(void);
> int spi_set_clock_rate(enum periph_id periph_id, unsigned int rate);
> +void clock_select_i2s_clk_source(void);
> +int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq);
> +int clock_epll_set_rate(unsigned long rate);
> #endif
> diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h
> index fce38ef..1df49a9 100644
> --- a/arch/arm/include/asm/arch-exynos/clock.h
> +++ b/arch/arm/include/asm/arch-exynos/clock.h
> @@ -595,9 +595,38 @@ struct exynos5_clock {
> unsigned int pll_div2_sel;
> unsigned char res123[0xf5d8];
> };
> +
> +/* structure for epll configuration used in audio clock configuration */
> +struct st_epll_con_val {
> + unsigned int freq_out; /* frequency out */
> + unsigned int en_lock_det; /* enable lock detect */
> + unsigned int m_div; /* m divider value */
> + unsigned int p_div; /* p divider value */
> + unsigned int s_div; /* s divider value */
> + unsigned int k_dsm; /* k value of delta signal modulator */
> +};
> #endif
>
> #define MPLL_FOUT_SEL_SHIFT 4
> +#define EXYNOS5_EPLLCON0_LOCKED_SHIFT 29 /* EPLL Locked bit position*/
> +#define TIMEOUT_EPLL_LOCK 1000
> +
> +#define AUDIO_0_RATIO_MASK 0x0f
> +#define AUDIO_1_RATIO_MASK 0x0f
> +
> +#define AUDIO1_SEL_MASK 0xf
> +#define CLK_SRC_SCLK_EPLL 0x7
> +
> +/* CON0 bit-fields */
> +#define EPLL_CON0_MDIV_MASK 0x1ff
> +#define EPLL_CON0_PDIV_MASK 0x3f
> +#define EPLL_CON0_SDIV_MASK 0x7
> +#define EPLL_CON0_MDIV_SHIFT 16
> +#define EPLL_CON0_PDIV_SHIFT 8
> +#define EPLL_CON0_SDIV_SHIFT 0
> +#define EPLL_CON0_LOCK_DET_EN_SHIFT 28
> +#define EPLL_CON0_LOCK_DET_EN_MASK 1
> +
> #define MPLL_FOUT_SEL_MASK 0x1
> #define BPLL_FOUT_SEL_SHIFT 0
> #define BPLL_FOUT_SEL_MASK 0x1
> --
> 1.7.4.4
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Thanks.
Minkyu Kang.
--
from. prom.
www.promsoft.net
More information about the U-Boot
mailing list