mmc: fsl_esdhc: Allow all supported prescaler values
Subsystems (2)
PATCH 1/4 mmc: fsl_esdhc: Allow all supported prescaler values
On i.MX, SYSCTL.SDCLKFS may be set to 0 in order to make the SD clock frequency prescaler divide by 1 in SDR mode. In DDR mode, the prescaler can divide by up to 512. Allow both of these settings.
The maximum SD clock frequency in High Speed mode is 50 MHz. On i.MX25, this change makes it possible to get 48 MHz from the USB PLL (240 MHz / 5 / 1) instead of only 40 MHz from the USB PLL (240 MHz / 3 / 2) or 33.25 MHz from the AHB clock (133 MHz / 2 / 2).
--- drivers/mmc/fsl_esdhc.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
drivers/mmc/fsl_esdhc.c +12 -11
@@ -521,7 +521,13 @@ out:static void set_sysctl (struct mmc *mmc,uint clock) { -int div, pre_div; +int div =1 ; +#ifdef ARCH_MXC +int pre_div =1 ; +#else +int pre_div =2 ; +#endif +int ddr_pre_div = mmc->ddr_mode ?2 :1 ;struct fsl_esdhc_priv *priv = mmc->priv;struct fsl_esdhc *regs = priv->esdhc_regs;int sdhc_clk = priv->sdhc_clk;
@@ -530,18 +536,13 @@ static void set_sysctl(struct mmc *mmc, uint clock)if (clock < mmc->cfg->f_min) clock = mmc->cfg->f_min; -if (sdhc_clk /16 > clock) { -for (pre_div =2 ; pre_div <256 ; pre_div *=2 ) -if ((sdhc_clk / pre_div) <= (clock *16 )) -break ; - }else - pre_div =2 ; +while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div <256 ) + pre_div *=2 ; -for (div =1 ; div <=16 ; div++) -if ((sdhc_clk / (div * pre_div)) <= clock) -break ; +while (sdhc_clk / (div * pre_div * ddr_pre_div) > clock && div <16 ) + div++; - pre_div >>= mmc->ddr_mode ?2 :1 ; + pre_div >>=1 ; div -=1 ; clk = (pre_div <<8 ) | (div <<4 );
Signature · 1 line
2.7.4
PATCH 2/4 mx25: Fix imx_get_perclk()
imx_get_perclk() used the AHB clock as the clock source for all PER clocks, but the USB PLL output can also be a PER clock source if the corresponding PER CLK MUX bit is set in CCM.MCR.
--- arch/arm/cpu/arm926ejs/mx25/generic.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +10 -1
@@ -58,6 +58,14 @@ static ulong imx_get_mpllclk(void)return imx_decode_pll (readl (&ccm->mpctl), fref); } +static ulong imx_get_upllclk (void ) +{ +struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE ; +ulong fref =MXC_HCLK ; + +return imx_decode_pll (readl (&ccm->upctl), fref); +} +static ulong imx_get_armclk (void ) {struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE ;
@@ -95,7 +103,8 @@ static ulong imx_get_ipgclk(void)static ulong imx_get_perclk (int clk) {struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE ; -ulong fref =imx_get_ahbclk (); +ulong fref =readl (&ccm->mcr) & (1 << clk) ?imx_get_upllclk () : +imx_get_ahbclk ();ulong div; div =readl (&ccm->pcdr[CCM_PERCLK_REG (clk)]);
Signature · 1 line
2.7.4
PATCH 2/4 mx25: Fix imx_get_perclk()
Quoted 5 lines · Benoît Thébaudeau
imx_get_perclk()used the AHB clock as the clock source for all PER clocks, but the USB PLL output can also be a PER clock source if the corresponding PER CLK MUX bit is set in CCM.MCR.Signed-off-by Benoît Thébaudeau <[email protected]>
PATCH 2/4 mx25: Fix imx_get_perclk()
In reply to Benoît ThébaudeauQuoted 30 lines · Benoît Thébaudeau
imx_get_perclk()used the AHB clock as the clock source for all PER clocks, but the USB PLL output can also be a PER clock source if the corresponding PER CLK MUX bit is set in CCM.MCR.Signed-off-by Benoît Thébaudeau <[email protected]>--- arch/arm/cpu/arm926ejs/mx25/generic.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)arch/arm/cpu/arm926ejs/mx25/generic.c +8
-0@@ -58,6 +58,14 @@ static ulong imx_get_mpllclk(void)return imx_decode_pll (readl (&ccm->mpctl), fref); } +static ulong imx_get_upllclk (void ) +{ +struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE ; +ulong fref =MXC_HCLK ; + +return imx_decode_pll (readl (&ccm->upctl), fref); +} +static ulong imx_get_armclk (void ) {struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE ;
arch/arm/cpu/arm926ejs/mx25/generic.c static ulong imx_get_ipgclk(void) · line 110
Quoted 9 lines
arch/arm/cpu/arm926ejs/mx25/generic.c +2
-1@@ -95,7 +103,8 @@ static ulong imx_get_ipgclk(void)static ulong imx_get_perclk (int clk) {struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE ; -ulong fref =imx_get_ahbclk (); +ulong fref =readl (&ccm->mcr) & (1 << clk) ?imx_get_upllclk () : +imx_get_ahbclk ();ulong div; div =readl (&ccm->pcdr[CCM_PERCLK_REG (clk)]);
Applied to u-boot-imx -master, thanks !
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================
PATCH 3/4 mx25: Add function to set PER clocks
In reply to Benoît ThébaudeauIntroduce the imx_set_perclk() function to make it possible to set the PER clocks.
--- arch/arm/cpu/arm926ejs/mx25/generic.c | 19 +++++++++++++++++++ arch/arm/include/asm/arch-mx25/clock.h | 1 + 2 files changed, 20 insertions(+)
arch/arm/cpu/arm926ejs/mx25/generic.c +19 -0
@@ -113,6 +113,25 @@ static ulong imx_get_perclk(int clk)return fref / div; } +int imx_set_perclk (enum mxc_clock clk,bool from_upll,unsigned int freq) +{ +struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE ; +ulong fref = from_upll ?imx_get_upllclk () :imx_get_ahbclk (); +ulong div = (fref + freq -1 ) / freq; + +if (clk >MXC_UART_CLK || !div || --div >CCM_PERCLK_MASK ) +return -EINVAL ; + +clrsetbits_le32 (&ccm->pcdr[CCM_PERCLK_REG (clk)], +CCM_PERCLK_MASK <<CCM_PERCLK_SHIFT (clk), + div <<CCM_PERCLK_SHIFT (clk)); +if (from_upll) +setbits_le32 (&ccm->mcr,1 << clk); +else +clrbits_le32 (&ccm->mcr,1 << clk); +return 0 ; +} +unsigned int mxc_get_clock (enum mxc_clock clk) {if (clk >=MXC_CLK_NUM )
arch/arm/include/asm/arch-mx25/clock.h +1 -0
@@ -51,6 +51,7 @@ enum mxc_clock { MXC_CLK_NUM }; +int imx_set_perclk (enum mxc_clock clk,bool from_upll,unsigned int freq);unsigned int mxc_get_clock (enum mxc_clock clk);#define imx_get_uartclk () mxc_get_clock(MXC_UART_CLK)
Signature · 1 line
2.7.4
PATCH 3/4 mx25: Add function to set PER clocks
Quoted 4 lines · Benoît Thébaudeau
Introduce the
imx_set_perclk()function to make it possible to set the PER clocks.Signed-off-by Benoît Thébaudeau <[email protected]>
PATCH 3/4 mx25: Add function to set PER clocks
In reply to Benoît ThébaudeauQuoted 45 lines · Benoît Thébaudeau
Introduce the
imx_set_perclk()function to make it possible to set the PER clocks.Signed-off-by Benoît Thébaudeau <[email protected]>--- arch/arm/cpu/arm926ejs/mx25/generic.c | 19 +++++++++++++++++++ arch/arm/include/asm/arch-mx25/clock.h | 1 + 2 files changed, 20 insertions(+)arch/arm/cpu/arm926ejs/mx25/generic.c +19
-0@@ -113,6 +113,25 @@ static ulong imx_get_perclk(int clk)return fref / div; } +int imx_set_perclk (enum mxc_clock clk,bool from_upll,unsigned int freq) +{ +struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE ; +ulong fref = from_upll ?imx_get_upllclk () :imx_get_ahbclk (); +ulong div = (fref + freq -1 ) / freq; + +if (clk >MXC_UART_CLK || !div || --div >CCM_PERCLK_MASK ) +return -EINVAL ; + +clrsetbits_le32 (&ccm->pcdr[CCM_PERCLK_REG (clk)], +CCM_PERCLK_MASK <<CCM_PERCLK_SHIFT (clk), + div <<CCM_PERCLK_SHIFT (clk)); +if (from_upll) +setbits_le32 (&ccm->mcr,1 << clk); +else +clrbits_le32 (&ccm->mcr,1 << clk); +return 0 ; +} +unsigned int mxc_get_clock (enum mxc_clock clk) {if (clk >=MXC_CLK_NUM )arch/arm/include/asm/arch-mx25/clock.h +0
-0
arch/arm/include/asm/arch-mx25/clock.h enum mxc_clock { · line 57
Quoted 7 lines
arch/arm/include/asm/arch-mx25/clock.h +1
-0@@ -51,6 +51,7 @@ enum mxc_clock { MXC_CLK_NUM }; +int imx_set_perclk (enum mxc_clock clk,bool from_upll,unsigned int freq);unsigned int mxc_get_clock (enum mxc_clock clk);#define imx_get_uartclk () mxc_get_clock(MXC_UART_CLK)
Applied to u-boot-imx -master, thanks !
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================
PATCH 4/4 mx25pdk: Set the eSDHC PER clock to 48 MHz
In reply to Benoît ThébaudeauThe maximum SD clock frequency in High Speed mode is 50 MHz. This change makes it possible to get 48 MHz from the USB PLL (240 MHz / 5 / 1) instead of the previous 33.25 MHz from the AHB clock (133 MHz / 2 / 2).
--- board/freescale/mx25pdk/mx25pdk.c | 6 ++++++ 1 file changed, 6 insertions(+)
board/freescale/mx25pdk/mx25pdk.c +6 -0
@@ -175,6 +175,12 @@ int board_mmc_init(bd_t *bis)imx_iomux_v3_setup_multiple_pads (sdhc1_pads,ARRAY_SIZE (sdhc1_pads)); +/* +* Set the eSDHC1 PER clock to the maximum frequency lower than or equal +* to 50 MHz that can be obtained, which requires to use UPLL as the +* clock source. This actually gives 48 MHz. +*/ +imx_set_perclk (MXC_ESDHC1_CLK , true,50000000 ); esdhc_cfg[0 ].sdhc_clk =mxc_get_clock (MXC_ESDHC1_CLK );return fsl_esdhc_initialize (bis, &esdhc_cfg[0 ]); }
Signature · 1 line
2.7.4
PATCH 4/4 mx25pdk: Set the eSDHC PER clock to 48 MHz
Quoted 5 lines · Benoît Thébaudeau
The maximum SD clock frequency in High Speed mode is 50 MHz. This change makes it possible to get 48 MHz from the USB PLL (240 MHz / 5 / 1) instead of the previous 33.25 MHz from the AHB clock (133 MHz / 2 / 2).
Signed-off-by Benoît Thébaudeau <[email protected]>
PATCH 4/4 mx25pdk: Set the eSDHC PER clock to 48 MHz
In reply to Benoît ThébaudeauQuoted 17 lines · Benoît Thébaudeau
The maximum SD clock frequency in High Speed mode is 50 MHz. This change makes it possible to get 48 MHz from the USB PLL (240 MHz / 5 / 1) instead of the previous 33.25 MHz from the AHB clock (133 MHz / 2 / 2).
Signed-off-by Benoît Thébaudeau <[email protected]>--- board/freescale/mx25pdk/mx25pdk.c | 6 ++++++ 1 file changed, 6 insertions(+)board/freescale/mx25pdk/mx25pdk.c +0
-0@@ -175,6 +175,12 @@ int board_mmc_init(bd_t *bis)imx_iomux_v3_setup_multiple_pads (sdhc1_pads,ARRAY_SIZE (sdhc1_pads));
board/freescale/mx25pdk/mx25pdk.c int board_mmc_init(bd_t *bis) · line 186
Quoted 10 lines
board/freescale/mx25pdk/mx25pdk.c +6
-0+/* +* Set the eSDHC1 PER clock to the maximum frequency lower than or equal +* to 50 MHz that can be obtained, which requires to use UPLL as the +* clock source. This actually gives 48 MHz. +*/ +imx_set_perclk (MXC_ESDHC1_CLK , true,50000000 ); esdhc_cfg[0 ].sdhc_clk =mxc_get_clock (MXC_ESDHC1_CLK );return fsl_esdhc_initialize (bis, &esdhc_cfg[0 ]); }
Applied to u-boot-imx -master, thanks !
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================
PATCH 1/4 mmc: fsl_esdhc: Allow all supported prescaler values
In reply to Benoît ThébaudeauQuoted 10 lines · Benoît Thébaudeau
On i.MX, SYSCTL.SDCLKFS may be set to 0 in order to make the SD clock frequency prescaler divide by 1 in SDR mode. In DDR mode, the prescaler can divide by up to 512. Allow both of these settings.
The maximum SD clock frequency in High Speed mode is 50 MHz. On i.MX25, this change makes it possible to get 48 MHz from the USB PLL (240 MHz / 5 / 1) instead of only 40 MHz from the USB PLL (240 MHz / 3 / 2) or 33.25 MHz from the AHB clock (133 MHz / 2 / 2).
Signed-off-by Benoît Thébaudeau <[email protected]>
PATCH 1/4 mmc: fsl_esdhc: Allow all supported prescaler values
In reply to Benoît ThébaudeauQuoted 48 lines · Benoît Thébaudeau
On i.MX, SYSCTL.SDCLKFS may be set to 0 in order to make the SD clock frequency prescaler divide by 1 in SDR mode. In DDR mode, the prescaler can divide by up to 512. Allow both of these settings.
The maximum SD clock frequency in High Speed mode is 50 MHz. On i.MX25, this change makes it possible to get 48 MHz from the USB PLL (240 MHz / 5 / 1) instead of only 40 MHz from the USB PLL (240 MHz / 3 / 2) or 33.25 MHz from the AHB clock (133 MHz / 2 / 2).
Signed-off-by Benoît Thébaudeau <[email protected]>--- drivers/mmc/fsl_esdhc.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)drivers/mmc/fsl_esdhc.c +9
-8@@ -521,7 +521,13 @@ out:static void set_sysctl (struct mmc *mmc,uint clock) { -int div, pre_div; +int div =1 ; +#ifdef ARCH_MXC +int pre_div =1 ; +#else +int pre_div =2 ; +#endif +int ddr_pre_div = mmc->ddr_mode ?2 :1 ;struct fsl_esdhc_priv *priv = mmc->priv;struct fsl_esdhc *regs = priv->esdhc_regs;int sdhc_clk = priv->sdhc_clk;@@ -530,18 +536,13 @@ static void set_sysctl(struct mmc *mmc, uint clock)if (clock < mmc->cfg->f_min) clock = mmc->cfg->f_min; -if (sdhc_clk /16 > clock) { -for (pre_div =2 ; pre_div <256 ; pre_div *=2 ) -if ((sdhc_clk / pre_div) <= (clock *16 )) -break ; - }else - pre_div =2 ; +while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div <256 ) + pre_div *=2 ; -for (div =1 ; div <=16 ; div++)
drivers/mmc/fsl_esdhc.c static void set_sysctl(struct mmc *mmc, uint clock) · line 548
Quoted 10 lines
drivers/mmc/fsl_esdhc.c +3
-3-if ((sdhc_clk / (div * pre_div)) <= clock) -break ; +while (sdhc_clk / (div * pre_div * ddr_pre_div) > clock && div <16 ) + div++; - pre_div >>= mmc->ddr_mode ?2 :1 ; + pre_div >>=1 ; div -=1 ; clk = (pre_div <<8 ) | (div <<4 );
Applied to u-boot-imx -master, thanks !
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================