Message ID | 20250421030008.1172901-1-ricky_wu@realtek.com |
---|---|
State | New |
Headers | show |
Series | [v2] mmc: rtsx: usb add 74 clocks in poweron flow | expand |
On Mon, 21 Apr 2025 at 05:00, Ricky Wu <ricky_wu@realtek.com> wrote: > > SD spec definition: > "Host provides at least 74 Clocks before issuing first command" > > add if statement to issue/stop the clock signal to card: > The power state from POWER_OFF to POWER_UP issue the signal to card, > POWER_UP to POWER_ON stop the signal We should never go from POWER_UP to POWER_ON. Perhaps what you mean is POWER_UP to POWER_OFF? > > Signed-off-by: Ricky Wu <ricky_wu@realtek.com> > --- > > v2: remove delay 100ms in power_on > --- > drivers/mmc/host/rtsx_usb_sdmmc.c | 26 +++++++++++++++++++++++--- > 1 file changed, 23 insertions(+), 3 deletions(-) > > diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c > index d229c2b83ea9..1edfe2acf809 100644 > --- a/drivers/mmc/host/rtsx_usb_sdmmc.c > +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c > @@ -48,7 +48,7 @@ struct rtsx_usb_sdmmc { > bool ddr_mode; > > unsigned char power_mode; > - > + unsigned char prev_power_mode; > #ifdef RTSX_USB_USE_LEDS_CLASS > struct led_classdev led; > char led_name[32]; > @@ -1014,6 +1014,16 @@ static int sd_set_power_mode(struct rtsx_usb_sdmmc *host, > unsigned char power_mode) > { > int err; > + int power_mode_temp; > + struct rtsx_ucr *ucr = host->ucr; > + > + power_mode_temp = power_mode; > + > + if ((power_mode == MMC_POWER_ON) && (host->power_mode == MMC_POWER_ON) && > + (host->prev_power_mode == MMC_POWER_UP)) { > + host->prev_power_mode = MMC_POWER_ON; > + rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00); > + } > > if (power_mode != MMC_POWER_OFF) > power_mode = MMC_POWER_ON; > @@ -1029,9 +1039,18 @@ static int sd_set_power_mode(struct rtsx_usb_sdmmc *host, > err = sd_power_on(host); > } > > - if (!err) > - host->power_mode = power_mode; > + if (!err) { > + if ((power_mode_temp == MMC_POWER_UP) && (host->power_mode == MMC_POWER_OFF)) { > + host->prev_power_mode = MMC_POWER_UP; > + rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, > + SD_CLK_TOGGLE_EN); > + } > + > + if ((power_mode_temp == MMC_POWER_OFF) && (host->power_mode == MMC_POWER_ON)) > + host->prev_power_mode = MMC_POWER_OFF; > > + host->power_mode = power_mode; > + } This looks unnecessarily complicated to me. May I suggest you start with a patch that converts the current code into using a switch-case-clause and just check if ("host->power_mode == power_mode") to understand if there are some actions you need to do. On top of that, I think the change you are trying to do should be far easier to implement. Can you please give this a try? > return err; > } > > @@ -1316,6 +1335,7 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host) > mmc->max_req_size = 524288; > > host->power_mode = MMC_POWER_OFF; > + host->prev_power_mode = MMC_POWER_OFF; > } > > static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev) > -- > 2.25.1 > Kind regards Uffe
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c index d229c2b83ea9..1edfe2acf809 100644 --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -48,7 +48,7 @@ struct rtsx_usb_sdmmc { bool ddr_mode; unsigned char power_mode; - + unsigned char prev_power_mode; #ifdef RTSX_USB_USE_LEDS_CLASS struct led_classdev led; char led_name[32]; @@ -1014,6 +1014,16 @@ static int sd_set_power_mode(struct rtsx_usb_sdmmc *host, unsigned char power_mode) { int err; + int power_mode_temp; + struct rtsx_ucr *ucr = host->ucr; + + power_mode_temp = power_mode; + + if ((power_mode == MMC_POWER_ON) && (host->power_mode == MMC_POWER_ON) && + (host->prev_power_mode == MMC_POWER_UP)) { + host->prev_power_mode = MMC_POWER_ON; + rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00); + } if (power_mode != MMC_POWER_OFF) power_mode = MMC_POWER_ON; @@ -1029,9 +1039,18 @@ static int sd_set_power_mode(struct rtsx_usb_sdmmc *host, err = sd_power_on(host); } - if (!err) - host->power_mode = power_mode; + if (!err) { + if ((power_mode_temp == MMC_POWER_UP) && (host->power_mode == MMC_POWER_OFF)) { + host->prev_power_mode = MMC_POWER_UP; + rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, + SD_CLK_TOGGLE_EN); + } + + if ((power_mode_temp == MMC_POWER_OFF) && (host->power_mode == MMC_POWER_ON)) + host->prev_power_mode = MMC_POWER_OFF; + host->power_mode = power_mode; + } return err; } @@ -1316,6 +1335,7 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host) mmc->max_req_size = 524288; host->power_mode = MMC_POWER_OFF; + host->prev_power_mode = MMC_POWER_OFF; } static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
SD spec definition: "Host provides at least 74 Clocks before issuing first command" add if statement to issue/stop the clock signal to card: The power state from POWER_OFF to POWER_UP issue the signal to card, POWER_UP to POWER_ON stop the signal Signed-off-by: Ricky Wu <ricky_wu@realtek.com> --- v2: remove delay 100ms in power_on --- drivers/mmc/host/rtsx_usb_sdmmc.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-)