diff mbox series

mmc: mmci: stm32: set feedback clock when using delay block

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

Commit Message

Yann Gautier June 13, 2023, 3:01 p.m. UTC
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>
---
 drivers/mmc/host/mmci_stm32_sdmmc.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

Comments

Ulf Hansson June 14, 2023, 10:31 a.m. UTC | #1
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 mbox series

Patch

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;