Linux-mmc Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] mmc: Some Micron eMMC devices cause reboot to hang
@ 2020-07-21 19:17 Al Cooper
  2020-07-24 11:03 ` Ulf Hansson
  0 siblings, 1 reply; 3+ messages in thread
From: Al Cooper @ 2020-07-21 19:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Cooper, Bradley Bolen, linux-mmc, Pali Rohár, Ulf Hansson

When using eMMC as the boot device, some Micron eMMC devices will
cause reboot to hang. This is a result of the eMMC device not going
into boot mode after the hardware sends CMD0 to reset the eMMC
device. This only happens if the kernel driver sends CMD5 (SLEEP_WAKE),
to put the device into sleep state, before restarting the system.
The fix is to add a quirk that avoids sending the SLEEP command
and to use MMC_FIXUP to set the quirk for these Micron devices.

Signed-off-by: Al Cooper <alcooperx@gmail.com>
---
 drivers/mmc/core/mmc.c    | 3 ++-
 drivers/mmc/core/quirks.h | 8 ++++++++
 include/linux/mmc/card.h  | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 4203303f946a..4d69e8f8fe59 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1895,7 +1895,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 
 static int mmc_can_sleep(struct mmc_card *card)
 {
-	return (card && card->ext_csd.rev >= 3);
+	return card && card->ext_csd.rev >= 3 &&
+		((card->quirks & MMC_QUIRK_BROKEN_SLEEP) == 0);
 }
 
 static int mmc_sleep(struct mmc_host *host)
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
index 472fa2fdcf13..7263187b6323 100644
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -99,6 +99,14 @@ static const struct mmc_fixup mmc_blk_fixups[] = {
 	MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
 		  MMC_QUIRK_TRIM_BROKEN),
 
+	/*
+	 * Some Micron eMMC devices will not go into boot mode on
+	 * CMD0 arg: 0XF0F0F0F0 after going into SLEEP state.
+	 * This will hang a reboot.
+	 */
+	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_NUMONYX, 0x014e, add_quirk_mmc,
+		  MMC_QUIRK_BROKEN_SLEEP),
+
 	END_FIXUP
 };
 
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 7d46411ffaa2..0cdddcb5e17d 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -270,6 +270,7 @@ struct mmc_card {
 #define MMC_QUIRK_BROKEN_IRQ_POLLING	(1<<11)	/* Polling SDIO_CCCR_INTx could create a fake interrupt */
 #define MMC_QUIRK_TRIM_BROKEN	(1<<12)		/* Skip trim */
 #define MMC_QUIRK_BROKEN_HPI	(1<<13)		/* Disable broken HPI support */
+#define MMC_QUIRK_BROKEN_SLEEP	(1<<14)		/* Broken sleep mode */
 
 	bool			reenable_cmdq;	/* Re-enable Command Queue */
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] mmc: Some Micron eMMC devices cause reboot to hang
  2020-07-21 19:17 [PATCH] mmc: Some Micron eMMC devices cause reboot to hang Al Cooper
@ 2020-07-24 11:03 ` Ulf Hansson
  2020-07-27 13:07   ` Alan Cooper
  0 siblings, 1 reply; 3+ messages in thread
From: Ulf Hansson @ 2020-07-24 11:03 UTC (permalink / raw)
  To: Al Cooper
  Cc: Linux Kernel Mailing List, Bradley Bolen, linux-mmc, Pali Rohár

On Tue, 21 Jul 2020 at 21:18, Al Cooper <alcooperx@gmail.com> wrote:
>
> When using eMMC as the boot device, some Micron eMMC devices will
> cause reboot to hang. This is a result of the eMMC device not going
> into boot mode after the hardware sends CMD0 to reset the eMMC
> device. This only happens if the kernel driver sends CMD5 (SLEEP_WAKE),
> to put the device into sleep state, before restarting the system.

What do you mean by "boot mode"?

When the kernel sends the CMD0 to wake up the eMMC from sleep, at
system resume for example, it all works fine, I guess. What is the
difference?

> The fix is to add a quirk that avoids sending the SLEEP command
> and to use MMC_FIXUP to set the quirk for these Micron devices.

I am not sure this is Micron device specific, but rather some it's a
driver/platform bug. Maybe on the kernel side or in the bootloader
code.

But, let's see where the discussion leads us.

Kind regards
Uffe

>
> Signed-off-by: Al Cooper <alcooperx@gmail.com>
> ---
>  drivers/mmc/core/mmc.c    | 3 ++-
>  drivers/mmc/core/quirks.h | 8 ++++++++
>  include/linux/mmc/card.h  | 1 +
>  3 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 4203303f946a..4d69e8f8fe59 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -1895,7 +1895,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>
>  static int mmc_can_sleep(struct mmc_card *card)
>  {
> -       return (card && card->ext_csd.rev >= 3);
> +       return card && card->ext_csd.rev >= 3 &&
> +               ((card->quirks & MMC_QUIRK_BROKEN_SLEEP) == 0);
>  }
>
>  static int mmc_sleep(struct mmc_host *host)
> diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
> index 472fa2fdcf13..7263187b6323 100644
> --- a/drivers/mmc/core/quirks.h
> +++ b/drivers/mmc/core/quirks.h
> @@ -99,6 +99,14 @@ static const struct mmc_fixup mmc_blk_fixups[] = {
>         MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
>                   MMC_QUIRK_TRIM_BROKEN),
>
> +       /*
> +        * Some Micron eMMC devices will not go into boot mode on
> +        * CMD0 arg: 0XF0F0F0F0 after going into SLEEP state.
> +        * This will hang a reboot.
> +        */
> +       MMC_FIXUP(CID_NAME_ANY, CID_MANFID_NUMONYX, 0x014e, add_quirk_mmc,
> +                 MMC_QUIRK_BROKEN_SLEEP),
> +
>         END_FIXUP
>  };
>
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 7d46411ffaa2..0cdddcb5e17d 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -270,6 +270,7 @@ struct mmc_card {
>  #define MMC_QUIRK_BROKEN_IRQ_POLLING   (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */
>  #define MMC_QUIRK_TRIM_BROKEN  (1<<12)         /* Skip trim */
>  #define MMC_QUIRK_BROKEN_HPI   (1<<13)         /* Disable broken HPI support */
> +#define MMC_QUIRK_BROKEN_SLEEP (1<<14)         /* Broken sleep mode */
>
>         bool                    reenable_cmdq;  /* Re-enable Command Queue */
>
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] mmc: Some Micron eMMC devices cause reboot to hang
  2020-07-24 11:03 ` Ulf Hansson
@ 2020-07-27 13:07   ` Alan Cooper
  0 siblings, 0 replies; 3+ messages in thread
From: Alan Cooper @ 2020-07-27 13:07 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Linux Kernel Mailing List, Bradley Bolen, linux-mmc, Pali Rohár

On Fri, Jul 24, 2020 at 7:03 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> On Tue, 21 Jul 2020 at 21:18, Al Cooper <alcooperx@gmail.com> wrote:
> >
> > When using eMMC as the boot device, some Micron eMMC devices will
> > cause reboot to hang. This is a result of the eMMC device not going
> > into boot mode after the hardware sends CMD0 to reset the eMMC
> > device. This only happens if the kernel driver sends CMD5 (SLEEP_WAKE),
> > to put the device into sleep state, before restarting the system.
>
> What do you mean by "boot mode"?

I'm referring to the "Boot operation mode" described in Section 6.3 of
the JEDEC spec.
Our hardware will send a CMD0 with 0xf0f0f0f0 argument at powerup or
when the SoC is reset, and then hold the CLK signal low for 74 clock
cycles. This should put the eMMC device into boot mode where it
streams consecutive blocks without additional commands. With this
Micron device I find that if I send a CMD5 before trying to restart
the system by resetting the SoC, that the system hangs. I worked with
Micron on the issue and they finally said to either avoid sending the
CMD5 on restart or use a newer version of the Micron eMMC device.


>
> When the kernel sends the CMD0 to wake up the eMMC from sleep, at
> system resume for example, it all works fine, I guess. What is the
> difference?

On system resume the hardware will not try to put the eMMC device back
into boot mode.

Al

>
> > The fix is to add a quirk that avoids sending the SLEEP command
> > and to use MMC_FIXUP to set the quirk for these Micron devices.
>
> I am not sure this is Micron device specific, but rather some it's a
> driver/platform bug. Maybe on the kernel side or in the bootloader
> code.
>
> But, let's see where the discussion leads us.
>
> Kind regards
> Uffe
>
> >
> > Signed-off-by: Al Cooper <alcooperx@gmail.com>
> > ---
> >  drivers/mmc/core/mmc.c    | 3 ++-
> >  drivers/mmc/core/quirks.h | 8 ++++++++
> >  include/linux/mmc/card.h  | 1 +
> >  3 files changed, 11 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> > index 4203303f946a..4d69e8f8fe59 100644
> > --- a/drivers/mmc/core/mmc.c
> > +++ b/drivers/mmc/core/mmc.c
> > @@ -1895,7 +1895,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> >
> >  static int mmc_can_sleep(struct mmc_card *card)
> >  {
> > -       return (card && card->ext_csd.rev >= 3);
> > +       return card && card->ext_csd.rev >= 3 &&
> > +               ((card->quirks & MMC_QUIRK_BROKEN_SLEEP) == 0);
> >  }
> >
> >  static int mmc_sleep(struct mmc_host *host)
> > diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
> > index 472fa2fdcf13..7263187b6323 100644
> > --- a/drivers/mmc/core/quirks.h
> > +++ b/drivers/mmc/core/quirks.h
> > @@ -99,6 +99,14 @@ static const struct mmc_fixup mmc_blk_fixups[] = {
> >         MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
> >                   MMC_QUIRK_TRIM_BROKEN),
> >
> > +       /*
> > +        * Some Micron eMMC devices will not go into boot mode on
> > +        * CMD0 arg: 0XF0F0F0F0 after going into SLEEP state.
> > +        * This will hang a reboot.
> > +        */
> > +       MMC_FIXUP(CID_NAME_ANY, CID_MANFID_NUMONYX, 0x014e, add_quirk_mmc,
> > +                 MMC_QUIRK_BROKEN_SLEEP),
> > +
> >         END_FIXUP
> >  };
> >
> > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> > index 7d46411ffaa2..0cdddcb5e17d 100644
> > --- a/include/linux/mmc/card.h
> > +++ b/include/linux/mmc/card.h
> > @@ -270,6 +270,7 @@ struct mmc_card {
> >  #define MMC_QUIRK_BROKEN_IRQ_POLLING   (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */
> >  #define MMC_QUIRK_TRIM_BROKEN  (1<<12)         /* Skip trim */
> >  #define MMC_QUIRK_BROKEN_HPI   (1<<13)         /* Disable broken HPI support */
> > +#define MMC_QUIRK_BROKEN_SLEEP (1<<14)         /* Broken sleep mode */
> >
> >         bool                    reenable_cmdq;  /* Re-enable Command Queue */
> >
> > --
> > 2.17.1
> >

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, back to index

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-21 19:17 [PATCH] mmc: Some Micron eMMC devices cause reboot to hang Al Cooper
2020-07-24 11:03 ` Ulf Hansson
2020-07-27 13:07   ` Alan Cooper

Linux-mmc Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-mmc/0 linux-mmc/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-mmc linux-mmc/ https://lore.kernel.org/linux-mmc \
		linux-mmc@vger.kernel.org
	public-inbox-index linux-mmc

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-mmc


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git