From mboxrd@z Thu Jan 1 00:00:00 1970 From: Joonyoung Shim Date: Tue, 03 Feb 2015 14:23:37 +0900 Subject: [U-Boot] [PATCH v4 6/6] Exynos: clock: change mask bits as per peripheral In-Reply-To: <1422879558-23792-7-git-send-email-akshay.s@samsung.com> References: <1422879558-23792-1-git-send-email-akshay.s@samsung.com> <1422879558-23792-7-git-send-email-akshay.s@samsung.com> Message-ID: <54D05B59.30600@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 Hi, On 02/02/2015 09:19 PM, Akshay Saraswat wrote: > We have assumed and kept mask bits for divider and pre-divider > as 0xf and 0xff, respectively. But these mask bits change from > one peripheral to another, and hence, need to be specified in > accordance with the peripherals. > > Signed-off-by: Akshay Saraswat > --- > Changes since v3: > - New patch. > > arch/arm/cpu/armv7/exynos/clock.c | 268 +++++++++++++++++++------------------- > 1 file changed, 135 insertions(+), 133 deletions(-) > > diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c > index f19fb5c..4feb5ba 100644 > --- a/arch/arm/cpu/armv7/exynos/clock.c > +++ b/arch/arm/cpu/armv7/exynos/clock.c > @@ -21,79 +21,83 @@ > */ > struct clk_bit_info { > enum periph_id id; > + int32_t src_mask; > + int32_t div_mask; > + int32_t prediv_mask; > int8_t src_bit; > int8_t div_bit; > int8_t prediv_bit; > }; > > -/* periph_id src_bit div_bit prediv_bit */ > static struct clk_bit_info exynos5_bit_info[] = { > - {PERIPH_ID_UART0, 0, 0, -1}, > - {PERIPH_ID_UART1, 4, 4, -1}, > - {PERIPH_ID_UART2, 8, 8, -1}, > - {PERIPH_ID_UART3, 12, 12, -1}, > - {PERIPH_ID_I2C0, -1, 24, 0}, > - {PERIPH_ID_I2C1, -1, 24, 0}, > - {PERIPH_ID_I2C2, -1, 24, 0}, > - {PERIPH_ID_I2C3, -1, 24, 0}, > - {PERIPH_ID_I2C4, -1, 24, 0}, > - {PERIPH_ID_I2C5, -1, 24, 0}, > - {PERIPH_ID_I2C6, -1, 24, 0}, > - {PERIPH_ID_I2C7, -1, 24, 0}, > - {PERIPH_ID_SPI0, 16, 0, 8}, > - {PERIPH_ID_SPI1, 20, 16, 24}, > - {PERIPH_ID_SPI2, 24, 0, 8}, > - {PERIPH_ID_SDMMC0, 0, 0, 8}, > - {PERIPH_ID_SDMMC1, 4, 16, 24}, > - {PERIPH_ID_SDMMC2, 8, 0, 8}, > - {PERIPH_ID_SDMMC3, 12, 16, 24}, > - {PERIPH_ID_I2S0, 0, 0, 4}, > - {PERIPH_ID_I2S1, 4, 12, 16}, > - {PERIPH_ID_SPI3, 0, 0, 4}, > - {PERIPH_ID_SPI4, 4, 12, 16}, > - {PERIPH_ID_SDMMC4, 16, 0, 8}, > - {PERIPH_ID_PWM0, 24, 0, -1}, > - {PERIPH_ID_PWM1, 24, 0, -1}, > - {PERIPH_ID_PWM2, 24, 0, -1}, > - {PERIPH_ID_PWM3, 24, 0, -1}, > - {PERIPH_ID_PWM4, 24, 0, -1}, > - > - {PERIPH_ID_NONE, -1, -1, -1}, > + /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ > + {PERIPH_ID_UART0, 0xf, 0xf, -1, 0, 0, -1}, > + {PERIPH_ID_UART1, 0xf, 0xf, -1, 4, 4, -1}, > + {PERIPH_ID_UART2, 0xf, 0xf, -1, 8, 8, -1}, > + {PERIPH_ID_UART3, 0xf, 0xf, -1, 12, 12, -1}, > + {PERIPH_ID_I2C0, -1, 0x7, 0x7, -1, 24, 0}, > + {PERIPH_ID_I2C1, -1, 0x7, 0x7, -1, 24, 0}, > + {PERIPH_ID_I2C2, -1, 0x7, 0x7, -1, 24, 0}, > + {PERIPH_ID_I2C3, -1, 0x7, 0x7, -1, 24, 0}, > + {PERIPH_ID_I2C4, -1, 0x7, 0x7, -1, 24, 0}, > + {PERIPH_ID_I2C5, -1, 0x7, 0x7, -1, 24, 0}, > + {PERIPH_ID_I2C6, -1, 0x7, 0x7, -1, 24, 0}, > + {PERIPH_ID_I2C7, -1, 0x7, 0x7, -1, 24, 0}, > + {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 16, 0, 8}, > + {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 20, 16, 24}, > + {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 24, 0, 8}, > + {PERIPH_ID_SDMMC0, 0xf, 0xf, 0xff, 0, 0, 8}, > + {PERIPH_ID_SDMMC1, 0xf, 0xf, 0xff, 4, 16, 24}, > + {PERIPH_ID_SDMMC2, 0xf, 0xf, 0xff, 8, 0, 8}, > + {PERIPH_ID_SDMMC3, 0xf, 0xf, 0xff, 12, 16, 24}, > + {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, > + {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, > + {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 0, 0, 4}, > + {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 4, 12, 16}, > + {PERIPH_ID_SDMMC4, 0xf, 0xf, 0xff, 16, 0, 8}, > + {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 0, -1}, > + {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 0, -1}, > + {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 0, -1}, > + {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 0, -1}, > + {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 0, -1}, > + > + {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, > }; > > static struct clk_bit_info exynos542x_bit_info[] = { > - {PERIPH_ID_UART0, 4, 8, -1}, > - {PERIPH_ID_UART1, 8, 12, -1}, > - {PERIPH_ID_UART2, 12, 16, -1}, > - {PERIPH_ID_UART3, 16, 20, -1}, > - {PERIPH_ID_I2C0, -1, 8, -1}, > - {PERIPH_ID_I2C1, -1, 8, -1}, > - {PERIPH_ID_I2C2, -1, 8, -1}, > - {PERIPH_ID_I2C3, -1, 8, -1}, > - {PERIPH_ID_I2C4, -1, 8, -1}, > - {PERIPH_ID_I2C5, -1, 8, -1}, > - {PERIPH_ID_I2C6, -1, 8, -1}, > - {PERIPH_ID_I2C7, -1, 8, -1}, > - {PERIPH_ID_SPI0, 20, 20, 8}, > - {PERIPH_ID_SPI1, 24, 24, 16}, > - {PERIPH_ID_SPI2, 28, 28, 24}, > - {PERIPH_ID_SDMMC0, 8, 0, -1}, > - {PERIPH_ID_SDMMC1, 12, 10, -1}, > - {PERIPH_ID_SDMMC2, 16, 20, -1}, > - {PERIPH_ID_I2C8, -1, 8, -1}, > - {PERIPH_ID_I2C9, -1, 8, -1}, > - {PERIPH_ID_I2S0, 0, 0, 4}, > - {PERIPH_ID_I2S1, 4, 12, 16}, > - {PERIPH_ID_SPI3, 12, 16, 0}, > - {PERIPH_ID_SPI4, 16, 20, 8}, > - {PERIPH_ID_PWM0, 24, 28, -1}, > - {PERIPH_ID_PWM1, 24, 28, -1}, > - {PERIPH_ID_PWM2, 24, 28, -1}, > - {PERIPH_ID_PWM3, 24, 28, -1}, > - {PERIPH_ID_PWM4, 24, 28, -1}, > - {PERIPH_ID_I2C10, -1, 8, -1}, > - > - {PERIPH_ID_NONE, -1, -1, -1}, > + /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ > + {PERIPH_ID_UART0, 0xf, 0xf, -1, 4, 8, -1}, > + {PERIPH_ID_UART1, 0xf, 0xf, -1, 8, 12, -1}, > + {PERIPH_ID_UART2, 0xf, 0xf, -1, 12, 16, -1}, > + {PERIPH_ID_UART3, 0xf, 0xf, -1, 16, 20, -1}, > + {PERIPH_ID_I2C0, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2C1, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2C2, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2C3, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2C4, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2C5, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2C6, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2C7, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 20, 20, 8}, > + {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 24, 24, 16}, > + {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 28, 28, 24}, > + {PERIPH_ID_SDMMC0, 0x7, 0x3ff, -1, 8, 0, -1}, > + {PERIPH_ID_SDMMC1, 0x7, 0x3ff, -1, 12, 10, -1}, > + {PERIPH_ID_SDMMC2, 0x7, 0x3ff, -1, 16, 20, -1}, > + {PERIPH_ID_I2C8, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2C9, -1, 0x3f, -1, -1, 8, -1}, > + {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, > + {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, > + {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 12, 16, 0}, > + {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 16, 20, 8}, > + {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 28, -1}, > + {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 28, -1}, > + {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 28, -1}, > + {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 28, -1}, > + {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 28, -1}, > + {PERIPH_ID_I2C10, -1, 0x3f, -1, -1, 8, -1}, > + > + {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, > }; > > /* Epll Clock division values to achive different frequency output */ > @@ -362,8 +366,8 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral) > static unsigned long exynos5_get_periph_rate(int peripheral) > { > struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); > - unsigned long sclk, sub_clk = 0; > - unsigned int src, div, sub_div = 0; > + unsigned long sclk = 0; > + unsigned int src = 0, div = 0, sub_div = 0; > struct exynos5_clock *clk = > (struct exynos5_clock *)samsung_get_base_clock(); > > @@ -385,30 +389,30 @@ static unsigned long exynos5_get_periph_rate(int peripheral) > break; > case PERIPH_ID_I2S0: > src = readl(&clk->src_mau); > - div = readl(&clk->div_mau); > + div = sub_div = readl(&clk->div_mau); > case PERIPH_ID_SPI0: > case PERIPH_ID_SPI1: > src = readl(&clk->src_peric1); > - div = readl(&clk->div_peric1); > + div = sub_div = readl(&clk->div_peric1); > break; > case PERIPH_ID_SPI2: > src = readl(&clk->src_peric1); > - div = readl(&clk->div_peric2); > + div = sub_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); > + div = sub_div = readl(&clk->sclk_div_isp); > break; > case PERIPH_ID_SDMMC0: > case PERIPH_ID_SDMMC1: > src = readl(&clk->src_fsys); > - div = readl(&clk->div_fsys1); > + div = sub_div = readl(&clk->div_fsys1); > break; > case PERIPH_ID_SDMMC2: > case PERIPH_ID_SDMMC3: > src = readl(&clk->src_fsys); > - div = readl(&clk->div_fsys2); > + div = sub_div = readl(&clk->div_fsys2); > break; > case PERIPH_ID_I2C0: > case PERIPH_ID_I2C1: > @@ -419,52 +423,51 @@ static unsigned long exynos5_get_periph_rate(int peripheral) > 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; > + div = readl(&clk->div_top0); > + sub_div = readl(&clk->div_top1); > + break; This isn't associated with to consider mask bits. > default: > debug("%s: invalid peripheral %d", __func__, peripheral); > return -1; > }; > > - if (bit_info->src_bit >= 0) > - src = (src >> bit_info->src_bit) & 0xf; > + /* Get src clock for this peripheral */ > + if (bit_info->src_bit >= 0) { > + src = (src >> bit_info->src_bit) & bit_info->src_mask; > > - switch (src) { > - case EXYNOS_SRC_MPLL: > - sclk = exynos5_get_pll_clk(MPLL); > - break; > - case EXYNOS_SRC_EPLL: > - sclk = exynos5_get_pll_clk(EPLL); > - break; > - case EXYNOS_SRC_VPLL: > - sclk = exynos5_get_pll_clk(VPLL); > - break; > - default: > - return 0; > + switch (src) { > + case EXYNOS_SRC_MPLL: > + sclk = exynos5_get_pll_clk(MPLL); > + break; > + case EXYNOS_SRC_EPLL: > + sclk = exynos5_get_pll_clk(EPLL); > + break; > + case EXYNOS_SRC_VPLL: > + sclk = exynos5_get_pll_clk(VPLL); > + break; > + default: > + return 0; > + } Ditto also to move in brace. Should go to patch4? > } > > - /* Ratio clock division for this peripheral */ > - if (bit_info->div_bit >= 0) { > - sub_div = (div >> bit_info->div_bit) & 0xf; > - sub_clk = sclk / (sub_div + 1); > - } > + /* Clock divider ratio for this peripheral */ > + if (bit_info->div_bit >= 0) > + div = (div >> bit_info->div_bit) & bit_info->div_mask; > > - if (bit_info->prediv_bit >= 0) { > - div = (div >> bit_info->prediv_bit) & 0xff; > - return sub_clk / (div + 1); > - } > + /* Clock pre-divider ratio for this peripheral */ > + if (bit_info->prediv_bit >= 0) > + sub_div = (sub_div >> bit_info->prediv_bit) > + & bit_info->prediv_mask; > > - return sub_clk; As i said above, I think it's better to split changes to clean and combine codes to get sub_clk. > + /* Calculate and return required clock rate */ > + return (sclk / (div + 1)) / (sub_div + 1); > } > > static unsigned long exynos542x_get_periph_rate(int peripheral) Same comments with exynos5_get_periph_rate. Thanks. > { > struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); > - unsigned long sclk, sub_clk = 0; > - unsigned int src, div, sub_div = 0; > + unsigned long sclk = 0; > + unsigned int src = 0, div = 0, sub_div = 0; > struct exynos5420_clock *clk = > (struct exynos5420_clock *)samsung_get_base_clock(); > > @@ -513,46 +516,45 @@ static unsigned long exynos542x_get_periph_rate(int peripheral) > case PERIPH_ID_I2C9: > case PERIPH_ID_I2C10: > sclk = exynos542x_get_pll_clk(MPLL); > - sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) > - & 0x7) + 1; > - return sclk / sub_div; > + div = readl(&clk->div_top1); > + break; > default: > debug("%s: invalid peripheral %d", __func__, peripheral); > return -1; > }; > > - if (bit_info->src_bit >= 0) > - src = (src >> bit_info->src_bit) & 0xf; > + if (bit_info->src_bit >= 0) { > + src = (src >> bit_info->src_bit) & bit_info->src_mask; > > - switch (src) { > - case EXYNOS542X_SRC_MPLL: > - sclk = exynos542x_get_pll_clk(MPLL); > - break; > - case EXYNOS542X_SRC_SPLL: > - sclk = exynos542x_get_pll_clk(SPLL); > - break; > - case EXYNOS542X_SRC_EPLL: > - sclk = exynos542x_get_pll_clk(EPLL); > - break; > - case EXYNOS542X_SRC_RPLL: > - sclk = exynos542x_get_pll_clk(RPLL); > - break; > - default: > - return 0; > + switch (src) { > + case EXYNOS542X_SRC_MPLL: > + sclk = exynos542x_get_pll_clk(MPLL); > + break; > + case EXYNOS542X_SRC_SPLL: > + sclk = exynos542x_get_pll_clk(SPLL); > + break; > + case EXYNOS542X_SRC_EPLL: > + sclk = exynos542x_get_pll_clk(EPLL); > + break; > + case EXYNOS542X_SRC_RPLL: > + sclk = exynos542x_get_pll_clk(RPLL); > + break; > + default: > + return 0; > + } > } > > - /* Ratio clock division for this peripheral */ > - if (bit_info->div_bit >= 0) { > - div = (div >> bit_info->div_bit) & 0xf; > - sub_clk = sclk / (div + 1); > - } > + /* Clock divider ratio for this peripheral */ > + if (bit_info->div_bit >= 0) > + div = (div >> bit_info->div_bit) & bit_info->div_mask; > > - if (bit_info->prediv_bit >= 0) { > - sub_div = (sub_div >> bit_info->prediv_bit) & 0xff; > - return sub_clk / (sub_div + 1); > - } > + /* Clock pre-divider ratio for this peripheral */ > + if (bit_info->prediv_bit >= 0) > + sub_div = (sub_div >> bit_info->prediv_bit) > + & bit_info->prediv_mask; > > - return sub_clk; > + /* Calculate and return required clock rate */ > + return (sclk / (div + 1)) / (sub_div + 1); > } > > unsigned long clock_get_periph_rate(int peripheral) >