Message ID | 20230613150148.429828-1-yann.gautier@foss.st.com |
---|---|
State | New |
Headers | show |
Series | mmc: mmci: stm32: set feedback clock when using delay block | expand |
On Tue, 13 Jun 2023 at 17:02, Yann Gautier <yann.gautier@foss.st.com> wrote: > > The feedback clock is used only for SDR104 & HS200 modes, and when > delay block is used (frequency is higher than 50 MHz). The tuning > procedure is then only required for those modes. Skip the procedure > for other modes. > The setting of this feedback clock is done just after enabling delay > block, and before configuring it. > > Signed-off-by: Yann Gautier <yann.gautier@foss.st.com> > Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com> Applied for next, thanks! Kind regards Uffe > --- > drivers/mmc/host/mmci_stm32_sdmmc.c | 29 ++++++++++++++++++----------- > 1 file changed, 18 insertions(+), 11 deletions(-) > > diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c > index 60bca78a72b19..953d1be4e379c 100644 > --- a/drivers/mmc/host/mmci_stm32_sdmmc.c > +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c > @@ -293,18 +293,8 @@ static void mmci_sdmmc_set_clkreg(struct mmci_host *host, unsigned int desired) > clk |= host->clk_reg_add; > clk |= ddr; > > - /* > - * SDMMC_FBCK is selected when an external Delay Block is needed > - * with SDR104 or HS200. > - */ > - if (host->mmc->ios.timing >= MMC_TIMING_UHS_SDR50) { > + if (host->mmc->ios.timing >= MMC_TIMING_UHS_SDR50) > clk |= MCI_STM32_CLK_BUSSPEED; > - if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104 || > - host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { > - clk &= ~MCI_STM32_CLK_SEL_MSK; > - clk |= MCI_STM32_CLK_SELFBCK; > - } > - } > > mmci_write_clkreg(host, clk); > } > @@ -511,10 +501,27 @@ static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode) > { > struct mmci_host *host = mmc_priv(mmc); > struct sdmmc_dlyb *dlyb = host->variant_priv; > + u32 clk; > + > + if ((host->mmc->ios.timing != MMC_TIMING_UHS_SDR104 && > + host->mmc->ios.timing != MMC_TIMING_MMC_HS200) || > + host->mmc->actual_clock <= 50000000) > + return 0; > > if (!dlyb || !dlyb->base) > return -EINVAL; > > + writel_relaxed(DLYB_CR_DEN, dlyb->base + DLYB_CR); > + > + /* > + * SDMMC_FBCK is selected when an external Delay Block is needed > + * with SDR104 or HS200. > + */ > + clk = host->clk_reg; > + clk &= ~MCI_STM32_CLK_SEL_MSK; > + clk |= MCI_STM32_CLK_SELFBCK; > + mmci_write_clkreg(host, clk); > + > if (sdmmc_dlyb_lng_tuning(host)) > return -EINVAL; > > -- > 2.25.1 >
diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c index 60bca78a72b19..953d1be4e379c 100644 --- a/drivers/mmc/host/mmci_stm32_sdmmc.c +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c @@ -293,18 +293,8 @@ static void mmci_sdmmc_set_clkreg(struct mmci_host *host, unsigned int desired) clk |= host->clk_reg_add; clk |= ddr; - /* - * SDMMC_FBCK is selected when an external Delay Block is needed - * with SDR104 or HS200. - */ - if (host->mmc->ios.timing >= MMC_TIMING_UHS_SDR50) { + if (host->mmc->ios.timing >= MMC_TIMING_UHS_SDR50) clk |= MCI_STM32_CLK_BUSSPEED; - if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104 || - host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { - clk &= ~MCI_STM32_CLK_SEL_MSK; - clk |= MCI_STM32_CLK_SELFBCK; - } - } mmci_write_clkreg(host, clk); } @@ -511,10 +501,27 @@ static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode) { struct mmci_host *host = mmc_priv(mmc); struct sdmmc_dlyb *dlyb = host->variant_priv; + u32 clk; + + if ((host->mmc->ios.timing != MMC_TIMING_UHS_SDR104 && + host->mmc->ios.timing != MMC_TIMING_MMC_HS200) || + host->mmc->actual_clock <= 50000000) + return 0; if (!dlyb || !dlyb->base) return -EINVAL; + writel_relaxed(DLYB_CR_DEN, dlyb->base + DLYB_CR); + + /* + * SDMMC_FBCK is selected when an external Delay Block is needed + * with SDR104 or HS200. + */ + clk = host->clk_reg; + clk &= ~MCI_STM32_CLK_SEL_MSK; + clk |= MCI_STM32_CLK_SELFBCK; + mmci_write_clkreg(host, clk); + if (sdmmc_dlyb_lng_tuning(host)) return -EINVAL;