diff mbox series

mmc: sdhci: Fix warning message when accessing RPMB in HS400 mode

Message ID 20210624163045.33651-1-alcooperx@gmail.com (mailing list archive)
State New, archived
Headers show
Series mmc: sdhci: Fix warning message when accessing RPMB in HS400 mode | expand

Commit Message

Alan Cooper June 24, 2021, 4:30 p.m. UTC
When an eMMC device is being run in HS400 mode, any access to the
RPMB device will cause the error message "mmc1: Invalid UHS-I mode
selected". This happens as a result of tuning being disabled before
RPMB access and then re-enabled after the RPMB access is complete.
When tuning is re-enabled, the system has to switch from HS400
to HS200 to do the tuning and then back to HS400. As part of
sequence to switch from HS400 to HS200 the system is temporarily
put into HS mode. When switching to HS mode, sdhci_get_preset_value()
is called and does not have support for HS mode and prints the warning
message and returns the preset for SDR12. The fix is to add support
for MMC and SD HS modes to sdhci_get_preset_value().

This can be reproduced on any system running eMMC in HS400 mode
(not HS400ES) by using the "mmc" utility to run the following
command: "mmc rpmb read-counter /dev/mmcblk0rpmb".

Signed-off-by: Al Cooper <alcooperx@gmail.com>
---
 drivers/mmc/host/sdhci.c | 4 ++++
 drivers/mmc/host/sdhci.h | 1 +
 2 files changed, 5 insertions(+)


base-commit: 7426cedc7dad67bf3c71ea6cc29ab7822e1a453f

Comments

Lai Jason June 28, 2021, 2:08 a.m. UTC | #1
Hi Ulf,
     In struct mmc_host, there was added a bit definition
'MMC_CAP2_SD_UHS2'(bit 9 of caps2).
     But there was already a definition 'MMC_CAP_UHS2'(bit 26 of caps).
     Do these two bit definitions work for the same purpose?

     By the way, where can I find the 2 source
codes(a/include/linux/mmc/ and b/include/linux/mmc/) which you diff
from.

> > ---
 diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
 index a001ad2f5f23..0a777caaf7f3 100644
 --- a/include/linux/mmc/host.h
 +++ b/include/linux/mmc/host.h

 @@ -377,6 +393,7 @@  struct mmc_host {
   MMC_CAP2_HS200_1_2V_SDR)
  #define MMC_CAP2_SD_EXP (1 << 7) /* SD express via PCIe */
  #define MMC_CAP2_SD_EXP_1_2V (1 << 8) /* SD express 1.2V */
 +#define MMC_CAP2_SD_UHS2 (1 << 9) /* SD UHS-II support */
  #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */
  #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal
active high */
  #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */


 best regards,
 Jason Lai
Adrian Hunter June 30, 2021, 12:52 p.m. UTC | #2
On 24/06/21 7:30 pm, Al Cooper wrote:
> When an eMMC device is being run in HS400 mode, any access to the
> RPMB device will cause the error message "mmc1: Invalid UHS-I mode
> selected". This happens as a result of tuning being disabled before
> RPMB access and then re-enabled after the RPMB access is complete.
> When tuning is re-enabled, the system has to switch from HS400
> to HS200 to do the tuning and then back to HS400. As part of
> sequence to switch from HS400 to HS200 the system is temporarily
> put into HS mode. When switching to HS mode, sdhci_get_preset_value()
> is called and does not have support for HS mode and prints the warning
> message and returns the preset for SDR12. The fix is to add support
> for MMC and SD HS modes to sdhci_get_preset_value().
> 
> This can be reproduced on any system running eMMC in HS400 mode
> (not HS400ES) by using the "mmc" utility to run the following
> command: "mmc rpmb read-counter /dev/mmcblk0rpmb".
> 
> Signed-off-by: Al Cooper <alcooperx@gmail.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  drivers/mmc/host/sdhci.c | 4 ++++
>  drivers/mmc/host/sdhci.h | 1 +
>  2 files changed, 5 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index bf238ade1602..6b39126fbf06 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1812,6 +1812,10 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
>  	u16 preset = 0;
>  
>  	switch (host->timing) {
> +	case MMC_TIMING_MMC_HS:
> +	case MMC_TIMING_SD_HS:
> +		preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED);
> +		break;
>  	case MMC_TIMING_UHS_SDR12:
>  		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
>  		break;
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 0770c036e2ff..960fed78529e 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -253,6 +253,7 @@
>  
>  /* 60-FB reserved */
>  
> +#define SDHCI_PRESET_FOR_HIGH_SPEED	0x64
>  #define SDHCI_PRESET_FOR_SDR12 0x66
>  #define SDHCI_PRESET_FOR_SDR25 0x68
>  #define SDHCI_PRESET_FOR_SDR50 0x6A
> 
> base-commit: 7426cedc7dad67bf3c71ea6cc29ab7822e1a453f
>
Ulf Hansson June 30, 2021, 2:20 p.m. UTC | #3
On Thu, 24 Jun 2021 at 18:31, Al Cooper <alcooperx@gmail.com> wrote:
>
> When an eMMC device is being run in HS400 mode, any access to the
> RPMB device will cause the error message "mmc1: Invalid UHS-I mode
> selected". This happens as a result of tuning being disabled before
> RPMB access and then re-enabled after the RPMB access is complete.
> When tuning is re-enabled, the system has to switch from HS400
> to HS200 to do the tuning and then back to HS400. As part of
> sequence to switch from HS400 to HS200 the system is temporarily
> put into HS mode. When switching to HS mode, sdhci_get_preset_value()
> is called and does not have support for HS mode and prints the warning
> message and returns the preset for SDR12. The fix is to add support
> for MMC and SD HS modes to sdhci_get_preset_value().
>
> This can be reproduced on any system running eMMC in HS400 mode
> (not HS400ES) by using the "mmc" utility to run the following
> command: "mmc rpmb read-counter /dev/mmcblk0rpmb".
>
> Signed-off-by: Al Cooper <alcooperx@gmail.com>

I assume we want this for stable kernels, but it would be nice to add
a fixes tag as well.

Do you know if there is a specific commit that this fixes?

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci.c | 4 ++++
>  drivers/mmc/host/sdhci.h | 1 +
>  2 files changed, 5 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index bf238ade1602..6b39126fbf06 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1812,6 +1812,10 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
>         u16 preset = 0;
>
>         switch (host->timing) {
> +       case MMC_TIMING_MMC_HS:
> +       case MMC_TIMING_SD_HS:
> +               preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED);
> +               break;
>         case MMC_TIMING_UHS_SDR12:
>                 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
>                 break;
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 0770c036e2ff..960fed78529e 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -253,6 +253,7 @@
>
>  /* 60-FB reserved */
>
> +#define SDHCI_PRESET_FOR_HIGH_SPEED    0x64
>  #define SDHCI_PRESET_FOR_SDR12 0x66
>  #define SDHCI_PRESET_FOR_SDR25 0x68
>  #define SDHCI_PRESET_FOR_SDR50 0x6A
>
> base-commit: 7426cedc7dad67bf3c71ea6cc29ab7822e1a453f
> --
> 2.17.1
>
Alan Cooper July 2, 2021, 12:33 p.m. UTC | #4
On Wed, Jun 30, 2021 at 10:21 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> On Thu, 24 Jun 2021 at 18:31, Al Cooper <alcooperx@gmail.com> wrote:
> >
> > When an eMMC device is being run in HS400 mode, any access to the
> > RPMB device will cause the error message "mmc1: Invalid UHS-I mode
> > selected". This happens as a result of tuning being disabled before
> > RPMB access and then re-enabled after the RPMB access is complete.
> > When tuning is re-enabled, the system has to switch from HS400
> > to HS200 to do the tuning and then back to HS400. As part of
> > sequence to switch from HS400 to HS200 the system is temporarily
> > put into HS mode. When switching to HS mode, sdhci_get_preset_value()
> > is called and does not have support for HS mode and prints the warning
> > message and returns the preset for SDR12. The fix is to add support
> > for MMC and SD HS modes to sdhci_get_preset_value().
> >
> > This can be reproduced on any system running eMMC in HS400 mode
> > (not HS400ES) by using the "mmc" utility to run the following
> > command: "mmc rpmb read-counter /dev/mmcblk0rpmb".
> >
> > Signed-off-by: Al Cooper <alcooperx@gmail.com>
>
> I assume we want this for stable kernels, but it would be nice to add
> a fixes tag as well.
>
> Do you know if there is a specific commit that this fixes?

The function sdhci_get_preset_value(), which is missing the HS modes,
was added in 52983382c74f5 for v3.9. Should I add a fixes tag for that
commit?

Thanks
Al

>
> Kind regards
> Uffe
>
> > ---
> >  drivers/mmc/host/sdhci.c | 4 ++++
> >  drivers/mmc/host/sdhci.h | 1 +
> >  2 files changed, 5 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> > index bf238ade1602..6b39126fbf06 100644
> > --- a/drivers/mmc/host/sdhci.c
> > +++ b/drivers/mmc/host/sdhci.c
> > @@ -1812,6 +1812,10 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
> >         u16 preset = 0;
> >
> >         switch (host->timing) {
> > +       case MMC_TIMING_MMC_HS:
> > +       case MMC_TIMING_SD_HS:
> > +               preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED);
> > +               break;
> >         case MMC_TIMING_UHS_SDR12:
> >                 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
> >                 break;
> > diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> > index 0770c036e2ff..960fed78529e 100644
> > --- a/drivers/mmc/host/sdhci.h
> > +++ b/drivers/mmc/host/sdhci.h
> > @@ -253,6 +253,7 @@
> >
> >  /* 60-FB reserved */
> >
> > +#define SDHCI_PRESET_FOR_HIGH_SPEED    0x64
> >  #define SDHCI_PRESET_FOR_SDR12 0x66
> >  #define SDHCI_PRESET_FOR_SDR25 0x68
> >  #define SDHCI_PRESET_FOR_SDR50 0x6A
> >
> > base-commit: 7426cedc7dad67bf3c71ea6cc29ab7822e1a453f
> > --
> > 2.17.1
> >
Ulf Hansson July 2, 2021, 1:22 p.m. UTC | #5
On Fri, 2 Jul 2021 at 14:34, Alan Cooper <alcooperx@gmail.com> wrote:
>
> On Wed, Jun 30, 2021 at 10:21 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> >
> > On Thu, 24 Jun 2021 at 18:31, Al Cooper <alcooperx@gmail.com> wrote:
> > >
> > > When an eMMC device is being run in HS400 mode, any access to the
> > > RPMB device will cause the error message "mmc1: Invalid UHS-I mode
> > > selected". This happens as a result of tuning being disabled before
> > > RPMB access and then re-enabled after the RPMB access is complete.
> > > When tuning is re-enabled, the system has to switch from HS400
> > > to HS200 to do the tuning and then back to HS400. As part of
> > > sequence to switch from HS400 to HS200 the system is temporarily
> > > put into HS mode. When switching to HS mode, sdhci_get_preset_value()
> > > is called and does not have support for HS mode and prints the warning
> > > message and returns the preset for SDR12. The fix is to add support
> > > for MMC and SD HS modes to sdhci_get_preset_value().
> > >
> > > This can be reproduced on any system running eMMC in HS400 mode
> > > (not HS400ES) by using the "mmc" utility to run the following
> > > command: "mmc rpmb read-counter /dev/mmcblk0rpmb".
> > >
> > > Signed-off-by: Al Cooper <alcooperx@gmail.com>
> >
> > I assume we want this for stable kernels, but it would be nice to add
> > a fixes tag as well.
> >
> > Do you know if there is a specific commit that this fixes?
>
> The function sdhci_get_preset_value(), which is missing the HS modes,
> was added in 52983382c74f5 for v3.9. Should I add a fixes tag for that
> commit?

Thanks for checking this! I have amended the patch to add a
fixes/stable tag and applied it for fixes.

Kind regards
Uffe

>
> Thanks
> Al
>
> >
> > Kind regards
> > Uffe
> >
> > > ---
> > >  drivers/mmc/host/sdhci.c | 4 ++++
> > >  drivers/mmc/host/sdhci.h | 1 +
> > >  2 files changed, 5 insertions(+)
> > >
> > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> > > index bf238ade1602..6b39126fbf06 100644
> > > --- a/drivers/mmc/host/sdhci.c
> > > +++ b/drivers/mmc/host/sdhci.c
> > > @@ -1812,6 +1812,10 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
> > >         u16 preset = 0;
> > >
> > >         switch (host->timing) {
> > > +       case MMC_TIMING_MMC_HS:
> > > +       case MMC_TIMING_SD_HS:
> > > +               preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED);
> > > +               break;
> > >         case MMC_TIMING_UHS_SDR12:
> > >                 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
> > >                 break;
> > > diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> > > index 0770c036e2ff..960fed78529e 100644
> > > --- a/drivers/mmc/host/sdhci.h
> > > +++ b/drivers/mmc/host/sdhci.h
> > > @@ -253,6 +253,7 @@
> > >
> > >  /* 60-FB reserved */
> > >
> > > +#define SDHCI_PRESET_FOR_HIGH_SPEED    0x64
> > >  #define SDHCI_PRESET_FOR_SDR12 0x66
> > >  #define SDHCI_PRESET_FOR_SDR25 0x68
> > >  #define SDHCI_PRESET_FOR_SDR50 0x6A
> > >
> > > base-commit: 7426cedc7dad67bf3c71ea6cc29ab7822e1a453f
> > > --
> > > 2.17.1
> > >
diff mbox series

Patch

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index bf238ade1602..6b39126fbf06 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1812,6 +1812,10 @@  static u16 sdhci_get_preset_value(struct sdhci_host *host)
 	u16 preset = 0;
 
 	switch (host->timing) {
+	case MMC_TIMING_MMC_HS:
+	case MMC_TIMING_SD_HS:
+		preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED);
+		break;
 	case MMC_TIMING_UHS_SDR12:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
 		break;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0770c036e2ff..960fed78529e 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -253,6 +253,7 @@ 
 
 /* 60-FB reserved */
 
+#define SDHCI_PRESET_FOR_HIGH_SPEED	0x64
 #define SDHCI_PRESET_FOR_SDR12 0x66
 #define SDHCI_PRESET_FOR_SDR25 0x68
 #define SDHCI_PRESET_FOR_SDR50 0x6A