diff mbox series

[v3] mmc: rtsx: usb add 74 clocks in poweron flow

Message ID 20250606030545.1743961-1-ricky_wu@realtek.com
State New
Headers show
Series [v3] mmc: rtsx: usb add 74 clocks in poweron flow | expand

Commit Message

Ricky Wu June 6, 2025, 3:05 a.m. UTC
SD spec definition:
"Host provides at least 74 Clocks before issuing first command"

add issue the clocks when power_mode is POWER_UP
and stop the signal when power_mode is POWER_up to POWER_ON

Signed-off-by: Ricky Wu <ricky_wu@realtek.com>
---
v2: remove delay 100ms in power_on
v3: Use switch-case instead of if statements
---
 drivers/mmc/host/rtsx_usb_sdmmc.c | 36 ++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 10 deletions(-)

Comments

Ulf Hansson June 10, 2025, 11:27 a.m. UTC | #1
On Fri, 6 Jun 2025 at 05:05, Ricky Wu <ricky_wu@realtek.com> wrote:
>
> SD spec definition:
> "Host provides at least 74 Clocks before issuing first command"
>
> add issue the clocks when power_mode is POWER_UP
> and stop the signal when power_mode is POWER_up to POWER_ON
>
> Signed-off-by: Ricky Wu <ricky_wu@realtek.com>

Thanks for trying to re-work the code according to my earlier
suggestions. However, $subject patch still seems a bit messy in my
opinion. I decided to try to help out a bit and posted a series [1],
please try to re-base your patch on top of this.

Kind regards
Uffe

[1]
https://lore.kernel.org/all/20250610111633.504366-1-ulf.hansson@linaro.org/

> ---
> v2: remove delay 100ms in power_on
> v3: Use switch-case instead of if statements
> ---
>  drivers/mmc/host/rtsx_usb_sdmmc.c | 36 ++++++++++++++++++++++---------
>  1 file changed, 26 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
> index d229c2b83ea9..1c808cfb44ff 100644
> --- a/drivers/mmc/host/rtsx_usb_sdmmc.c
> +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
> @@ -1014,24 +1014,40 @@ static int sd_set_power_mode(struct rtsx_usb_sdmmc *host,
>                 unsigned char power_mode)
>  {
>         int err;
> +       struct rtsx_ucr *ucr = host->ucr;
>
> -       if (power_mode != MMC_POWER_OFF)
> -               power_mode = MMC_POWER_ON;
> -
> -       if (power_mode == host->power_mode)
> -               return 0;
> -
> -       if (power_mode == MMC_POWER_OFF) {
> +       switch (power_mode) {
> +       case MMC_POWER_OFF:
> +               if (host->power_mode == MMC_POWER_OFF)
> +                       return 0;
>                 err = sd_power_off(host);
>                 pm_runtime_put_noidle(sdmmc_dev(host));
> -       } else {
> +               break;
> +       case MMC_POWER_UP:
> +       case MMC_POWER_ON:
> +               if (host->power_mode == MMC_POWER_ON) {
> +                       return 0;
> +               } else if (host->power_mode == MMC_POWER_UP) {
> +                       /* stop to send the clock signals */
> +                       rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00);
> +                       host->power_mode = power_mode;
> +                       return 0;
> +               }
>                 pm_runtime_get_noresume(sdmmc_dev(host));
>                 err = sd_power_on(host);
> +               break;
> +       default:
> +               return 0;
>         }
> +       if (!err) {
> +               if (power_mode == MMC_POWER_UP) {
> +                       /* issue the clock signals to card */
> +                       rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN,
> +                               SD_CLK_TOGGLE_EN);
> +               }
>
> -       if (!err)
>                 host->power_mode = power_mode;
> -
> +       }
>         return err;
>  }
>
> --
> 2.25.1
>
diff mbox series

Patch

diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
index d229c2b83ea9..1c808cfb44ff 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -1014,24 +1014,40 @@  static int sd_set_power_mode(struct rtsx_usb_sdmmc *host,
 		unsigned char power_mode)
 {
 	int err;
+	struct rtsx_ucr *ucr = host->ucr;
 
-	if (power_mode != MMC_POWER_OFF)
-		power_mode = MMC_POWER_ON;
-
-	if (power_mode == host->power_mode)
-		return 0;
-
-	if (power_mode == MMC_POWER_OFF) {
+	switch (power_mode) {
+	case MMC_POWER_OFF:
+		if (host->power_mode == MMC_POWER_OFF)
+			return 0;
 		err = sd_power_off(host);
 		pm_runtime_put_noidle(sdmmc_dev(host));
-	} else {
+		break;
+	case MMC_POWER_UP:
+	case MMC_POWER_ON:
+		if (host->power_mode == MMC_POWER_ON) {
+			return 0;
+		} else if (host->power_mode == MMC_POWER_UP) {
+			/* stop to send the clock signals */
+			rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00);
+			host->power_mode = power_mode;
+			return 0;
+		}
 		pm_runtime_get_noresume(sdmmc_dev(host));
 		err = sd_power_on(host);
+		break;
+	default:
+		return 0;
 	}
+	if (!err) {
+		if (power_mode == MMC_POWER_UP) {
+			/* issue the clock signals to card */
+			rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN,
+				SD_CLK_TOGGLE_EN);
+		}
 
-	if (!err)
 		host->power_mode = power_mode;
-
+	}
 	return err;
 }