diff mbox series

[v2,3/3] mmc: renesas-sdhi: Do not access SCC during tuning in send_cmd callback

Message ID 20240224223235.287889-3-marek.vasut+renesas@mailbox.org
State Accepted
Commit b78630630a9e419a50de986a3d268b428f5d0c28
Delegated to: Jaehoon Chung
Headers show
Series [v2,1/3] mmc: Convert hs400_tuning flag from u8 to bool | expand

Commit Message

Marek Vasut Feb. 24, 2024, 10:32 p.m. UTC
Do not access SCC when sending commands during tuning operation as that
will disrupt the tuning operation. The tuning operation is adjusting the
SCC settings itself in execute_tuning callback.

When renesas_sdhi_execute_tuning() is called by the MMC core code, a loop
which consists of renesas_sdhi_prepare_tuning(), mmc_send_tuning() and
renesas_sdhi_compare_scc_data() iterates over each SCC tuning tap.

The renesas_sdhi_prepare_tuning() configures the SCC tuning tap number into
hardware, mmc_send_tuning() triggers transfer of tuning block which depends
on the bus mode for which the bus is currently being tuned, this information
is supplied by the MMC core code, and finally renesas_sdhi_compare_scc_data()
tests the received tuning block for validity.

Because renesas_sdhi_prepare_tuning() configures the SCC tuning tap into
the hardware to fit the tuning operation, mmc_send_tuning() which triggers
command transfer using renesas_sdhi_send_cmd() must not manipulate with
the SCC in any way. Currently renesas_sdhi_send_cmd() does unconditionally
call renesas_sdhi_check_scc_error(), which may adjust the SCC tuning tap
position by writing RENESAS_SDHI_SCC_TAPSET, which would overwrite the
required tuning configuration set by renesas_sdhi_prepare_tuning() and
disrupt the tuning operation.

Fix this by skipping the renesas_sdhi_check_scc_error() call in case the
MMC subsystem is in tuning state. This way, the SCC settings are left
unmodified by command transfer during tuning operation.

Reviewed-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Tested-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Hai Pham <hai.pham.ud@renesas.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Cc: Paul Barker <paul.barker.ct@bp.renesas.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sean Anderson <seanga2@gmail.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
V2: Add RB/TB from Paul
---
 drivers/mmc/renesas-sdhi.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Jaehoon Chung April 3, 2024, 1:18 a.m. UTC | #1
On 2/25/24 07:32, Marek Vasut wrote:
> Do not access SCC when sending commands during tuning operation as that
> will disrupt the tuning operation. The tuning operation is adjusting the
> SCC settings itself in execute_tuning callback.
> 
> When renesas_sdhi_execute_tuning() is called by the MMC core code, a loop
> which consists of renesas_sdhi_prepare_tuning(), mmc_send_tuning() and
> renesas_sdhi_compare_scc_data() iterates over each SCC tuning tap.
> 
> The renesas_sdhi_prepare_tuning() configures the SCC tuning tap number into
> hardware, mmc_send_tuning() triggers transfer of tuning block which depends
> on the bus mode for which the bus is currently being tuned, this information
> is supplied by the MMC core code, and finally renesas_sdhi_compare_scc_data()
> tests the received tuning block for validity.
> 
> Because renesas_sdhi_prepare_tuning() configures the SCC tuning tap into
> the hardware to fit the tuning operation, mmc_send_tuning() which triggers
> command transfer using renesas_sdhi_send_cmd() must not manipulate with
> the SCC in any way. Currently renesas_sdhi_send_cmd() does unconditionally
> call renesas_sdhi_check_scc_error(), which may adjust the SCC tuning tap
> position by writing RENESAS_SDHI_SCC_TAPSET, which would overwrite the
> required tuning configuration set by renesas_sdhi_prepare_tuning() and
> disrupt the tuning operation.
> 
> Fix this by skipping the renesas_sdhi_check_scc_error() call in case the
> MMC subsystem is in tuning state. This way, the SCC settings are left
> unmodified by command transfer during tuning operation.
> 
> Reviewed-by: Paul Barker <paul.barker.ct@bp.renesas.com>
> Tested-by: Paul Barker <paul.barker.ct@bp.renesas.com>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
> Cc: Hai Pham <hai.pham.ud@renesas.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
> Cc: Paul Barker <paul.barker.ct@bp.renesas.com>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sean Anderson <seanga2@gmail.com>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
> V2: Add RB/TB from Paul
> ---
>  drivers/mmc/renesas-sdhi.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
> index 29a742f404e..c4d0733b621 100644
> --- a/drivers/mmc/renesas-sdhi.c
> +++ b/drivers/mmc/renesas-sdhi.c
> @@ -798,9 +798,12 @@ static int renesas_sdhi_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
>  #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
>      CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
>      CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> +	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
>  	struct tmio_sd_priv *priv = dev_get_priv(dev);
> +	struct mmc *mmc = upriv->mmc;
>  
> -	renesas_sdhi_check_scc_error(dev);
> +	if (!mmc->tuning)
> +		renesas_sdhi_check_scc_error(dev);
>  
>  	if (cmd->cmdidx == MMC_CMD_SEND_STATUS)
>  		renesas_sdhi_adjust_hs400_mode_enable(priv);
diff mbox series

Patch

diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 29a742f404e..c4d0733b621 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -798,9 +798,12 @@  static int renesas_sdhi_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
     CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
     CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct tmio_sd_priv *priv = dev_get_priv(dev);
+	struct mmc *mmc = upriv->mmc;
 
-	renesas_sdhi_check_scc_error(dev);
+	if (!mmc->tuning)
+		renesas_sdhi_check_scc_error(dev);
 
 	if (cmd->cmdidx == MMC_CMD_SEND_STATUS)
 		renesas_sdhi_adjust_hs400_mode_enable(priv);