diff mbox series

[v3,15/17] mtd: spi-nor-core: Perform a Soft Reset on boot

Message ID 20200330154550.21179-16-p.yadav@ti.com
State Superseded
Headers show
Series mtd: spi-nor-core: add xSPI Octal DTR support | expand

Commit Message

Pratyush Yadav March 30, 2020, 3:45 p.m. UTC
When the flash is handed to us in a stateful mode like 8D-8D-8D, it is
difficult to detect the mode the flash is in. One option is to read SFDP
in all modes and see which one gives the correct "SFDP" signature, but
not all flashes support SFDP in 8D-8D-8D mode.

Further, even if you detect the mode of the flash via SFDP, you still
have the problem of actually reading the ID. The Read ID command is not
standardized across flash vendors. Flashes can have different dummy
cycles needed for reading the ID. Some flashes even expect a 4-byte
dummy address with the Read ID command. All this information cannot be
obtained from the SFDP table.

So, perform a Software Reset sequence before reading the ID and
initializing the flash. A Soft Reset will bring back the flash in its
default protocol mode assuming no non-volatile configuration was set.
This will let us detect the flash even if ROM hands it to us in Octal
DTR mode.

To accommodate cases where there is more than one flash on a board, and
only one of them needs a soft reset, failure to reset is not made fatal,
and we still try to read ID if possible.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
---
 drivers/mtd/spi/Kconfig        | 11 +++++++++++
 drivers/mtd/spi/spi-nor-core.c | 27 +++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

Comments

Jagan Teki May 13, 2020, 6:47 a.m. UTC | #1
On Mon, Mar 30, 2020 at 9:16 PM Pratyush Yadav <p.yadav at ti.com> wrote:
>
> When the flash is handed to us in a stateful mode like 8D-8D-8D, it is
> difficult to detect the mode the flash is in. One option is to read SFDP
> in all modes and see which one gives the correct "SFDP" signature, but
> not all flashes support SFDP in 8D-8D-8D mode.
>
> Further, even if you detect the mode of the flash via SFDP, you still
> have the problem of actually reading the ID. The Read ID command is not
> standardized across flash vendors. Flashes can have different dummy
> cycles needed for reading the ID. Some flashes even expect a 4-byte
> dummy address with the Read ID command. All this information cannot be
> obtained from the SFDP table.
>
> So, perform a Software Reset sequence before reading the ID and
> initializing the flash. A Soft Reset will bring back the flash in its
> default protocol mode assuming no non-volatile configuration was set.
> This will let us detect the flash even if ROM hands it to us in Octal
> DTR mode.
>
> To accommodate cases where there is more than one flash on a board, and
> only one of them needs a soft reset, failure to reset is not made fatal,
> and we still try to read ID if possible.
>
> Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> ---
>  drivers/mtd/spi/Kconfig        | 11 +++++++++++
>  drivers/mtd/spi/spi-nor-core.c | 27 +++++++++++++++++++++++++++
>  2 files changed, 38 insertions(+)
>
> diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
> index 018e8c597e..38d509c568 100644
> --- a/drivers/mtd/spi/Kconfig
> +++ b/drivers/mtd/spi/Kconfig
> @@ -88,6 +88,17 @@ config SPI_FLASH_SFDP_SUPPORT
>          SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
>          tables as per JESD216 standard.
>
> +config SPI_FLASH_SOFT_RESET
> +       bool "Software Reset support for SPI NOR flashes"
> +       help
> +        Enable support for xSPI Software Reset. It will be used to switch
> +        from Octal DTR mode to legacy mode to allow detecting flashes that
> +        are handed to us in Octal DTR mode. It is expected that if the config
> +        is enabled the flash supports the Soft Reset sequence and is booted in
> +        Octal DTR mode. Do not enable this config on flashes that are not
> +        supposed to be handed to U-Boot in Octal DTR mode, even if they _do_
> +        support the Soft Reset sequence.
> +
>  config SPI_FLASH_BAR
>         bool "SPI flash Bank/Extended address register support"
>         help
> diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
> index 52b3775035..3af2c6afa9 100644
> --- a/drivers/mtd/spi/spi-nor-core.c
> +++ b/drivers/mtd/spi/spi-nor-core.c
> @@ -2922,6 +2922,33 @@ int spi_nor_scan(struct spi_nor *nor)
>
>         nor->setup = spi_nor_default_setup;
>
> +#if defined(CONFIG_SPI_FLASH_SOFT_RESET)
> +       /*
> +        * When the flash is handed to us in a stateful mode like 8D-8D-8D, it
> +        * is difficult to detect the mode the flash is in. One option is to
> +        * read SFDP in all modes and see which one gives the correct "SFDP"
> +        * signature, but not all flashes support SFDP in 8D-8D-8D mode.
> +        *
> +        * Further, even if you detect the mode of the flash via SFDP, you
> +        * still have the problem of actually reading the ID. The Read ID
> +        * command is not standardized across flash vendors. Flashes can have
> +        * different dummy cycles needed for reading the ID. Some flashes even
> +        * expect a 4-byte dummy address with the Read ID command. All this
> +        * information cannot be obtained from the SFDP table.
> +        *
> +        * So, perform a Software Reset sequence before reading the ID and
> +        * initializing the flash. A Soft Reset will bring back the flash in
> +        * its default protocol mode assuming no non-volatile configuration was
> +        * set. This will let us detect the flash even if ROM hands it to us in
> +        * Octal DTR mode.
> +        *
> +        * To accommodate cases where there is more than one flash on a board,
> +        * and only one of them needs a soft reset, failure to reset is not
> +        * made fatal, and we still try to read ID if possible.
> +        */
> +       spi_nor_soft_reset(nor);
> +#endif /* CONFIG_SPI_FLASH_SOFT_RESET */

Does it specific to a particular flash chip? I believe add flash chip
fixups would make more sense instead of having it like this.

Jagan.
Pratyush Yadav May 13, 2020, 8:54 a.m. UTC | #2
On 13/05/20 12:17PM, Jagan Teki wrote:
> On Mon, Mar 30, 2020 at 9:16 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> >
> > When the flash is handed to us in a stateful mode like 8D-8D-8D, it is
> > difficult to detect the mode the flash is in. One option is to read SFDP
> > in all modes and see which one gives the correct "SFDP" signature, but
> > not all flashes support SFDP in 8D-8D-8D mode.
> >
> > Further, even if you detect the mode of the flash via SFDP, you still
> > have the problem of actually reading the ID. The Read ID command is not
> > standardized across flash vendors. Flashes can have different dummy
> > cycles needed for reading the ID. Some flashes even expect a 4-byte
> > dummy address with the Read ID command. All this information cannot be
> > obtained from the SFDP table.
> >
> > So, perform a Software Reset sequence before reading the ID and
> > initializing the flash. A Soft Reset will bring back the flash in its
> > default protocol mode assuming no non-volatile configuration was set.
> > This will let us detect the flash even if ROM hands it to us in Octal
> > DTR mode.
> >
> > To accommodate cases where there is more than one flash on a board, and
> > only one of them needs a soft reset, failure to reset is not made fatal,
> > and we still try to read ID if possible.
> >
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > ---
> >  drivers/mtd/spi/Kconfig        | 11 +++++++++++
> >  drivers/mtd/spi/spi-nor-core.c | 27 +++++++++++++++++++++++++++
> >  2 files changed, 38 insertions(+)
> >
> > diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
> > index 018e8c597e..38d509c568 100644
> > --- a/drivers/mtd/spi/Kconfig
> > +++ b/drivers/mtd/spi/Kconfig
> > @@ -88,6 +88,17 @@ config SPI_FLASH_SFDP_SUPPORT
> >          SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
> >          tables as per JESD216 standard.
> >
> > +config SPI_FLASH_SOFT_RESET
> > +       bool "Software Reset support for SPI NOR flashes"
> > +       help
> > +        Enable support for xSPI Software Reset. It will be used to switch
> > +        from Octal DTR mode to legacy mode to allow detecting flashes that
> > +        are handed to us in Octal DTR mode. It is expected that if the config
> > +        is enabled the flash supports the Soft Reset sequence and is booted in
> > +        Octal DTR mode. Do not enable this config on flashes that are not
> > +        supposed to be handed to U-Boot in Octal DTR mode, even if they _do_
> > +        support the Soft Reset sequence.
> > +
> >  config SPI_FLASH_BAR
> >         bool "SPI flash Bank/Extended address register support"
> >         help
> > diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
> > index 52b3775035..3af2c6afa9 100644
> > --- a/drivers/mtd/spi/spi-nor-core.c
> > +++ b/drivers/mtd/spi/spi-nor-core.c
> > @@ -2922,6 +2922,33 @@ int spi_nor_scan(struct spi_nor *nor)
> >
> >         nor->setup = spi_nor_default_setup;
> >
> > +#if defined(CONFIG_SPI_FLASH_SOFT_RESET)
> > +       /*
> > +        * When the flash is handed to us in a stateful mode like 8D-8D-8D, it
> > +        * is difficult to detect the mode the flash is in. One option is to
> > +        * read SFDP in all modes and see which one gives the correct "SFDP"
> > +        * signature, but not all flashes support SFDP in 8D-8D-8D mode.
> > +        *
> > +        * Further, even if you detect the mode of the flash via SFDP, you
> > +        * still have the problem of actually reading the ID. The Read ID
> > +        * command is not standardized across flash vendors. Flashes can have
> > +        * different dummy cycles needed for reading the ID. Some flashes even
> > +        * expect a 4-byte dummy address with the Read ID command. All this
> > +        * information cannot be obtained from the SFDP table.
> > +        *
> > +        * So, perform a Software Reset sequence before reading the ID and
> > +        * initializing the flash. A Soft Reset will bring back the flash in
> > +        * its default protocol mode assuming no non-volatile configuration was
> > +        * set. This will let us detect the flash even if ROM hands it to us in
> > +        * Octal DTR mode.
> > +        *
> > +        * To accommodate cases where there is more than one flash on a board,
> > +        * and only one of them needs a soft reset, failure to reset is not
> > +        * made fatal, and we still try to read ID if possible.
> > +        */
> > +       spi_nor_soft_reset(nor);
> > +#endif /* CONFIG_SPI_FLASH_SOFT_RESET */
> 
> Does it specific to a particular flash chip? I believe add flash chip
> fixups would make more sense instead of having it like this.

To run a flash fixup, we need to know which flash it is. But if ROM 
hands us the flash in 8D mode, we can't reliably detect the ID of the 
flash since the Read ID command differs from one flash to another. For 
example, on the Cypress S28 flash family, the Read ID command in 8D mode  
expects 4 dummy address bytes and 3 dummy cycles. But on the Micron 
MT35XU flashes, Read ID in 8D needs 0 address bytes and 8 dummy cycles.

This works around the issue by issuing a soft reset command so even if 
the flash is in 8D mode, it gets switched back to 1S mode so we can 
detect it.
Jagan Teki May 13, 2020, 9:56 a.m. UTC | #3
On Wed, May 13, 2020 at 2:24 PM Pratyush Yadav <p.yadav at ti.com> wrote:
>
> On 13/05/20 12:17PM, Jagan Teki wrote:
> > On Mon, Mar 30, 2020 at 9:16 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> > >
> > > When the flash is handed to us in a stateful mode like 8D-8D-8D, it is
> > > difficult to detect the mode the flash is in. One option is to read SFDP
> > > in all modes and see which one gives the correct "SFDP" signature, but
> > > not all flashes support SFDP in 8D-8D-8D mode.
> > >
> > > Further, even if you detect the mode of the flash via SFDP, you still
> > > have the problem of actually reading the ID. The Read ID command is not
> > > standardized across flash vendors. Flashes can have different dummy
> > > cycles needed for reading the ID. Some flashes even expect a 4-byte
> > > dummy address with the Read ID command. All this information cannot be
> > > obtained from the SFDP table.
> > >
> > > So, perform a Software Reset sequence before reading the ID and
> > > initializing the flash. A Soft Reset will bring back the flash in its
> > > default protocol mode assuming no non-volatile configuration was set.
> > > This will let us detect the flash even if ROM hands it to us in Octal
> > > DTR mode.
> > >
> > > To accommodate cases where there is more than one flash on a board, and
> > > only one of them needs a soft reset, failure to reset is not made fatal,
> > > and we still try to read ID if possible.
> > >
> > > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > > ---
> > >  drivers/mtd/spi/Kconfig        | 11 +++++++++++
> > >  drivers/mtd/spi/spi-nor-core.c | 27 +++++++++++++++++++++++++++
> > >  2 files changed, 38 insertions(+)
> > >
> > > diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
> > > index 018e8c597e..38d509c568 100644
> > > --- a/drivers/mtd/spi/Kconfig
> > > +++ b/drivers/mtd/spi/Kconfig
> > > @@ -88,6 +88,17 @@ config SPI_FLASH_SFDP_SUPPORT
> > >          SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
> > >          tables as per JESD216 standard.
> > >
> > > +config SPI_FLASH_SOFT_RESET
> > > +       bool "Software Reset support for SPI NOR flashes"
> > > +       help
> > > +        Enable support for xSPI Software Reset. It will be used to switch
> > > +        from Octal DTR mode to legacy mode to allow detecting flashes that
> > > +        are handed to us in Octal DTR mode. It is expected that if the config
> > > +        is enabled the flash supports the Soft Reset sequence and is booted in
> > > +        Octal DTR mode. Do not enable this config on flashes that are not
> > > +        supposed to be handed to U-Boot in Octal DTR mode, even if they _do_
> > > +        support the Soft Reset sequence.
> > > +
> > >  config SPI_FLASH_BAR
> > >         bool "SPI flash Bank/Extended address register support"
> > >         help
> > > diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
> > > index 52b3775035..3af2c6afa9 100644
> > > --- a/drivers/mtd/spi/spi-nor-core.c
> > > +++ b/drivers/mtd/spi/spi-nor-core.c
> > > @@ -2922,6 +2922,33 @@ int spi_nor_scan(struct spi_nor *nor)
> > >
> > >         nor->setup = spi_nor_default_setup;
> > >
> > > +#if defined(CONFIG_SPI_FLASH_SOFT_RESET)
> > > +       /*
> > > +        * When the flash is handed to us in a stateful mode like 8D-8D-8D, it
> > > +        * is difficult to detect the mode the flash is in. One option is to
> > > +        * read SFDP in all modes and see which one gives the correct "SFDP"
> > > +        * signature, but not all flashes support SFDP in 8D-8D-8D mode.
> > > +        *
> > > +        * Further, even if you detect the mode of the flash via SFDP, you
> > > +        * still have the problem of actually reading the ID. The Read ID
> > > +        * command is not standardized across flash vendors. Flashes can have
> > > +        * different dummy cycles needed for reading the ID. Some flashes even
> > > +        * expect a 4-byte dummy address with the Read ID command. All this
> > > +        * information cannot be obtained from the SFDP table.
> > > +        *
> > > +        * So, perform a Software Reset sequence before reading the ID and
> > > +        * initializing the flash. A Soft Reset will bring back the flash in
> > > +        * its default protocol mode assuming no non-volatile configuration was
> > > +        * set. This will let us detect the flash even if ROM hands it to us in
> > > +        * Octal DTR mode.
> > > +        *
> > > +        * To accommodate cases where there is more than one flash on a board,
> > > +        * and only one of them needs a soft reset, failure to reset is not
> > > +        * made fatal, and we still try to read ID if possible.
> > > +        */
> > > +       spi_nor_soft_reset(nor);
> > > +#endif /* CONFIG_SPI_FLASH_SOFT_RESET */
> >
> > Does it specific to a particular flash chip? I believe add flash chip
> > fixups would make more sense instead of having it like this.
>
> To run a flash fixup, we need to know which flash it is. But if ROM
> hands us the flash in 8D mode, we can't reliably detect the ID of the
> flash since the Read ID command differs from one flash to another. For
> example, on the Cypress S28 flash family, the Read ID command in 8D mode
> expects 4 dummy address bytes and 3 dummy cycles. But on the Micron
> MT35XU flashes, Read ID in 8D needs 0 address bytes and 8 dummy cycles.
>
> This works around the issue by issuing a soft reset command so even if
> the flash is in 8D mode, it gets switched back to 1S mode so we can
> detect it.

I got this from the commit message, thanks. Point I'm trying to
understand here about can't we detect soft reset of associate flash
via some bits in SFDP? if yes then we can dynamically process the soft
reset on associated flash like quad enable does?

Jagan.
Pratyush Yadav May 13, 2020, 11:04 a.m. UTC | #4
On 13/05/20 03:26PM, Jagan Teki wrote:
> On Wed, May 13, 2020 at 2:24 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> >
> > On 13/05/20 12:17PM, Jagan Teki wrote:
> > > On Mon, Mar 30, 2020 at 9:16 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> > > >
> > > > When the flash is handed to us in a stateful mode like 8D-8D-8D, it is
> > > > difficult to detect the mode the flash is in. One option is to read SFDP
> > > > in all modes and see which one gives the correct "SFDP" signature, but
> > > > not all flashes support SFDP in 8D-8D-8D mode.
> > > >
> > > > Further, even if you detect the mode of the flash via SFDP, you still
> > > > have the problem of actually reading the ID. The Read ID command is not
> > > > standardized across flash vendors. Flashes can have different dummy
> > > > cycles needed for reading the ID. Some flashes even expect a 4-byte
> > > > dummy address with the Read ID command. All this information cannot be
> > > > obtained from the SFDP table.
> > > >
> > > > So, perform a Software Reset sequence before reading the ID and
> > > > initializing the flash. A Soft Reset will bring back the flash in its
> > > > default protocol mode assuming no non-volatile configuration was set.
> > > > This will let us detect the flash even if ROM hands it to us in Octal
> > > > DTR mode.
> > > >
> > > > To accommodate cases where there is more than one flash on a board, and
> > > > only one of them needs a soft reset, failure to reset is not made fatal,
> > > > and we still try to read ID if possible.
> > > >
> > > > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > > > ---
> > > >  drivers/mtd/spi/Kconfig        | 11 +++++++++++
> > > >  drivers/mtd/spi/spi-nor-core.c | 27 +++++++++++++++++++++++++++
> > > >  2 files changed, 38 insertions(+)
> > > >
> > > > diff --git a/drivers/mtd/spi/spi-nor-core.c 
> > > > b/drivers/mtd/spi/spi-nor-core.c
> > > > index 52b3775035..3af2c6afa9 100644
> > > > --- a/drivers/mtd/spi/spi-nor-core.c
> > > > +++ b/drivers/mtd/spi/spi-nor-core.c
> > > > @@ -2922,6 +2922,33 @@ int spi_nor_scan(struct spi_nor *nor)
> > > >
> > > >         nor->setup = spi_nor_default_setup;
> > > >
> > > > +#if defined(CONFIG_SPI_FLASH_SOFT_RESET)
> > > > +       /*
> > > > +        * When the flash is handed to us in a stateful mode like 8D-8D-8D, it
> > > > +        * is difficult to detect the mode the flash is in. One option is to
> > > > +        * read SFDP in all modes and see which one gives the correct "SFDP"
> > > > +        * signature, but not all flashes support SFDP in 8D-8D-8D mode.
> > > > +        *
> > > > +        * Further, even if you detect the mode of the flash via SFDP, you
> > > > +        * still have the problem of actually reading the ID. The Read ID
> > > > +        * command is not standardized across flash vendors. Flashes can have
> > > > +        * different dummy cycles needed for reading the ID. Some flashes even
> > > > +        * expect a 4-byte dummy address with the Read ID command. All this
> > > > +        * information cannot be obtained from the SFDP table.
> > > > +        *
> > > > +        * So, perform a Software Reset sequence before reading the ID and
> > > > +        * initializing the flash. A Soft Reset will bring back the flash in
> > > > +        * its default protocol mode assuming no non-volatile configuration was
> > > > +        * set. This will let us detect the flash even if ROM hands it to us in
> > > > +        * Octal DTR mode.
> > > > +        *
> > > > +        * To accommodate cases where there is more than one flash on a board,
> > > > +        * and only one of them needs a soft reset, failure to reset is not
> > > > +        * made fatal, and we still try to read ID if possible.
> > > > +        */
> > > > +       spi_nor_soft_reset(nor);
> > > > +#endif /* CONFIG_SPI_FLASH_SOFT_RESET */
> > >
> > > Does it specific to a particular flash chip? I believe add flash chip
> > > fixups would make more sense instead of having it like this.
> >
> > To run a flash fixup, we need to know which flash it is. But if ROM
> > hands us the flash in 8D mode, we can't reliably detect the ID of the
> > flash since the Read ID command differs from one flash to another. For
> > example, on the Cypress S28 flash family, the Read ID command in 8D mode
> > expects 4 dummy address bytes and 3 dummy cycles. But on the Micron
> > MT35XU flashes, Read ID in 8D needs 0 address bytes and 8 dummy cycles.
> >
> > This works around the issue by issuing a soft reset command so even if
> > the flash is in 8D mode, it gets switched back to 1S mode so we can
> > detect it.
> 
> I got this from the commit message, thanks. Point I'm trying to
> understand here about can't we detect soft reset of associate flash
> via some bits in SFDP? if yes then we can dynamically process the soft
> reset on associated flash like quad enable does?

If the device supports the Read SFDP command in 8D mode (it is optional 
as per JESD251), then we can detect soft reset support via BFPT DWORD 16 
bits 13:8.

If we go that path, we would need to take the below steps before we can 
proceed with the probe:

- Issue Read SFDP in 8D mode and see if we get the "SFDP" signature 
  correctly. If we don't, exit.

- Read BFPT in 8D mode, and see if Soft Reset is supported.

- If it is, issue a soft reset and go on as usual. If it isn't, error 
  out, and the probe fails.

The problem is, I'm not sure if controllers will be okay doing this on a 
flash that is in 1S mode. Say the controller expects the DQS line to 
toggle when the flash is sending data. Now, we tell the controller we 
will read 16 bytes (SFDP header), but since the flash is in 1S mode, it 
sees some other command and might not send out any data at all. In this 
case, will the controller hang, waiting forever for the flash to toggle 
DQS?

FWIW, the controller on our board (Cadence QSPI) doesn't hang. But I'm 
not sure how other controllers would react. That's why I went with the 
more minimal option. The soft reset sequence doesn't expect to receive 
any data. It only sends it.

If you think no contoller will trip over this, then I don't mind 
discovering Soft Reset capability via BFPT.
Jagan Teki May 15, 2020, 7:42 a.m. UTC | #5
On Wed, May 13, 2020 at 4:34 PM Pratyush Yadav <p.yadav at ti.com> wrote:
>
> On 13/05/20 03:26PM, Jagan Teki wrote:
> > On Wed, May 13, 2020 at 2:24 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> > >
> > > On 13/05/20 12:17PM, Jagan Teki wrote:
> > > > On Mon, Mar 30, 2020 at 9:16 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> > > > >
> > > > > When the flash is handed to us in a stateful mode like 8D-8D-8D, it is
> > > > > difficult to detect the mode the flash is in. One option is to read SFDP
> > > > > in all modes and see which one gives the correct "SFDP" signature, but
> > > > > not all flashes support SFDP in 8D-8D-8D mode.
> > > > >
> > > > > Further, even if you detect the mode of the flash via SFDP, you still
> > > > > have the problem of actually reading the ID. The Read ID command is not
> > > > > standardized across flash vendors. Flashes can have different dummy
> > > > > cycles needed for reading the ID. Some flashes even expect a 4-byte
> > > > > dummy address with the Read ID command. All this information cannot be
> > > > > obtained from the SFDP table.
> > > > >
> > > > > So, perform a Software Reset sequence before reading the ID and
> > > > > initializing the flash. A Soft Reset will bring back the flash in its
> > > > > default protocol mode assuming no non-volatile configuration was set.
> > > > > This will let us detect the flash even if ROM hands it to us in Octal
> > > > > DTR mode.
> > > > >
> > > > > To accommodate cases where there is more than one flash on a board, and
> > > > > only one of them needs a soft reset, failure to reset is not made fatal,
> > > > > and we still try to read ID if possible.
> > > > >
> > > > > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > > > > ---
> > > > >  drivers/mtd/spi/Kconfig        | 11 +++++++++++
> > > > >  drivers/mtd/spi/spi-nor-core.c | 27 +++++++++++++++++++++++++++
> > > > >  2 files changed, 38 insertions(+)
> > > > >
> > > > > diff --git a/drivers/mtd/spi/spi-nor-core.c
> > > > > b/drivers/mtd/spi/spi-nor-core.c
> > > > > index 52b3775035..3af2c6afa9 100644
> > > > > --- a/drivers/mtd/spi/spi-nor-core.c
> > > > > +++ b/drivers/mtd/spi/spi-nor-core.c
> > > > > @@ -2922,6 +2922,33 @@ int spi_nor_scan(struct spi_nor *nor)
> > > > >
> > > > >         nor->setup = spi_nor_default_setup;
> > > > >
> > > > > +#if defined(CONFIG_SPI_FLASH_SOFT_RESET)
> > > > > +       /*
> > > > > +        * When the flash is handed to us in a stateful mode like 8D-8D-8D, it
> > > > > +        * is difficult to detect the mode the flash is in. One option is to
> > > > > +        * read SFDP in all modes and see which one gives the correct "SFDP"
> > > > > +        * signature, but not all flashes support SFDP in 8D-8D-8D mode.
> > > > > +        *
> > > > > +        * Further, even if you detect the mode of the flash via SFDP, you
> > > > > +        * still have the problem of actually reading the ID. The Read ID
> > > > > +        * command is not standardized across flash vendors. Flashes can have
> > > > > +        * different dummy cycles needed for reading the ID. Some flashes even
> > > > > +        * expect a 4-byte dummy address with the Read ID command. All this
> > > > > +        * information cannot be obtained from the SFDP table.
> > > > > +        *
> > > > > +        * So, perform a Software Reset sequence before reading the ID and
> > > > > +        * initializing the flash. A Soft Reset will bring back the flash in
> > > > > +        * its default protocol mode assuming no non-volatile configuration was
> > > > > +        * set. This will let us detect the flash even if ROM hands it to us in
> > > > > +        * Octal DTR mode.
> > > > > +        *
> > > > > +        * To accommodate cases where there is more than one flash on a board,
> > > > > +        * and only one of them needs a soft reset, failure to reset is not
> > > > > +        * made fatal, and we still try to read ID if possible.
> > > > > +        */
> > > > > +       spi_nor_soft_reset(nor);
> > > > > +#endif /* CONFIG_SPI_FLASH_SOFT_RESET */
> > > >
> > > > Does it specific to a particular flash chip? I believe add flash chip
> > > > fixups would make more sense instead of having it like this.
> > >
> > > To run a flash fixup, we need to know which flash it is. But if ROM
> > > hands us the flash in 8D mode, we can't reliably detect the ID of the
> > > flash since the Read ID command differs from one flash to another. For
> > > example, on the Cypress S28 flash family, the Read ID command in 8D mode
> > > expects 4 dummy address bytes and 3 dummy cycles. But on the Micron
> > > MT35XU flashes, Read ID in 8D needs 0 address bytes and 8 dummy cycles.
> > >
> > > This works around the issue by issuing a soft reset command so even if
> > > the flash is in 8D mode, it gets switched back to 1S mode so we can
> > > detect it.
> >
> > I got this from the commit message, thanks. Point I'm trying to
> > understand here about can't we detect soft reset of associate flash
> > via some bits in SFDP? if yes then we can dynamically process the soft
> > reset on associated flash like quad enable does?
>
> If the device supports the Read SFDP command in 8D mode (it is optional
> as per JESD251), then we can detect soft reset support via BFPT DWORD 16
> bits 13:8.
>
> If we go that path, we would need to take the below steps before we can
> proceed with the probe:
>
> - Issue Read SFDP in 8D mode and see if we get the "SFDP" signature
>   correctly. If we don't, exit.
>
> - Read BFPT in 8D mode, and see if Soft Reset is supported.
>
> - If it is, issue a soft reset and go on as usual. If it isn't, error
>   out, and the probe fails.
>
> The problem is, I'm not sure if controllers will be okay doing this on a
> flash that is in 1S mode. Say the controller expects the DQS line to
> toggle when the flash is sending data. Now, we tell the controller we
> will read 16 bytes (SFDP header), but since the flash is in 1S mode, it
> sees some other command and might not send out any data at all. In this
> case, will the controller hang, waiting forever for the flash to toggle
> DQS?
>
> FWIW, the controller on our board (Cadence QSPI) doesn't hang. But I'm
> not sure how other controllers would react. That's why I went with the
> more minimal option. The soft reset sequence doesn't expect to receive
> any data. It only sends it.

So, we never sure if another controller (other than cadence) can
guarantee to toggle the DQS? Can't the flash wait till to controller
to toggle? I would like to see how this implemented in Linux, is it
under progress or done in similar way?

Jagan.
Pratyush Yadav May 19, 2020, 3:33 p.m. UTC | #6
On 15/05/20 01:12PM, Jagan Teki wrote:
> On Wed, May 13, 2020 at 4:34 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> >
> > On 13/05/20 03:26PM, Jagan Teki wrote:
> > > On Wed, May 13, 2020 at 2:24 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> > > >
> > > > On 13/05/20 12:17PM, Jagan Teki wrote:
> > > > > On Mon, Mar 30, 2020 at 9:16 PM Pratyush Yadav <p.yadav at ti.com> wrote:
> > > > > >
> > > > > > When the flash is handed to us in a stateful mode like 8D-8D-8D, it is
> > > > > > difficult to detect the mode the flash is in. One option is to read SFDP
> > > > > > in all modes and see which one gives the correct "SFDP" signature, but
> > > > > > not all flashes support SFDP in 8D-8D-8D mode.
> > > > > >
> > > > > > Further, even if you detect the mode of the flash via SFDP, you still
> > > > > > have the problem of actually reading the ID. The Read ID command is not
> > > > > > standardized across flash vendors. Flashes can have different dummy
> > > > > > cycles needed for reading the ID. Some flashes even expect a 4-byte
> > > > > > dummy address with the Read ID command. All this information cannot be
> > > > > > obtained from the SFDP table.
> > > > > >
> > > > > > So, perform a Software Reset sequence before reading the ID and
> > > > > > initializing the flash. A Soft Reset will bring back the flash in its
> > > > > > default protocol mode assuming no non-volatile configuration was set.
> > > > > > This will let us detect the flash even if ROM hands it to us in Octal
> > > > > > DTR mode.
> > > > > >
> > > > > > To accommodate cases where there is more than one flash on a board, and
> > > > > > only one of them needs a soft reset, failure to reset is not made fatal,
> > > > > > and we still try to read ID if possible.
> > > > > >
> > > > > > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > > > > > ---
> > > > > >  drivers/mtd/spi/Kconfig        | 11 +++++++++++
> > > > > >  drivers/mtd/spi/spi-nor-core.c | 27 +++++++++++++++++++++++++++
> > > > > >  2 files changed, 38 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/mtd/spi/spi-nor-core.c
> > > > > > b/drivers/mtd/spi/spi-nor-core.c
> > > > > > index 52b3775035..3af2c6afa9 100644
> > > > > > --- a/drivers/mtd/spi/spi-nor-core.c
> > > > > > +++ b/drivers/mtd/spi/spi-nor-core.c
> > > > > > @@ -2922,6 +2922,33 @@ int spi_nor_scan(struct spi_nor *nor)
> > > > > >
> > > > > >         nor->setup = spi_nor_default_setup;
> > > > > >
> > > > > > +#if defined(CONFIG_SPI_FLASH_SOFT_RESET)
> > > > > > +       /*
> > > > > > +        * When the flash is handed to us in a stateful mode like 8D-8D-8D, it
> > > > > > +        * is difficult to detect the mode the flash is in. One option is to
> > > > > > +        * read SFDP in all modes and see which one gives the correct "SFDP"
> > > > > > +        * signature, but not all flashes support SFDP in 8D-8D-8D mode.
> > > > > > +        *
> > > > > > +        * Further, even if you detect the mode of the flash via SFDP, you
> > > > > > +        * still have the problem of actually reading the ID. The Read ID
> > > > > > +        * command is not standardized across flash vendors. Flashes can have
> > > > > > +        * different dummy cycles needed for reading the ID. Some flashes even
> > > > > > +        * expect a 4-byte dummy address with the Read ID command. All this
> > > > > > +        * information cannot be obtained from the SFDP table.
> > > > > > +        *
> > > > > > +        * So, perform a Software Reset sequence before reading the ID and
> > > > > > +        * initializing the flash. A Soft Reset will bring back the flash in
> > > > > > +        * its default protocol mode assuming no non-volatile configuration was
> > > > > > +        * set. This will let us detect the flash even if ROM hands it to us in
> > > > > > +        * Octal DTR mode.
> > > > > > +        *
> > > > > > +        * To accommodate cases where there is more than one flash on a board,
> > > > > > +        * and only one of them needs a soft reset, failure to reset is not
> > > > > > +        * made fatal, and we still try to read ID if possible.
> > > > > > +        */
> > > > > > +       spi_nor_soft_reset(nor);
> > > > > > +#endif /* CONFIG_SPI_FLASH_SOFT_RESET */
> > > > >
> > > > > Does it specific to a particular flash chip? I believe add flash chip
> > > > > fixups would make more sense instead of having it like this.
> > > >
> > > > To run a flash fixup, we need to know which flash it is. But if ROM
> > > > hands us the flash in 8D mode, we can't reliably detect the ID of the
> > > > flash since the Read ID command differs from one flash to another. For
> > > > example, on the Cypress S28 flash family, the Read ID command in 8D mode
> > > > expects 4 dummy address bytes and 3 dummy cycles. But on the Micron
> > > > MT35XU flashes, Read ID in 8D needs 0 address bytes and 8 dummy cycles.
> > > >
> > > > This works around the issue by issuing a soft reset command so even if
> > > > the flash is in 8D mode, it gets switched back to 1S mode so we can
> > > > detect it.
> > >
> > > I got this from the commit message, thanks. Point I'm trying to
> > > understand here about can't we detect soft reset of associate flash
> > > via some bits in SFDP? if yes then we can dynamically process the soft
> > > reset on associated flash like quad enable does?
> >
> > If the device supports the Read SFDP command in 8D mode (it is optional
> > as per JESD251), then we can detect soft reset support via BFPT DWORD 16
> > bits 13:8.
> >
> > If we go that path, we would need to take the below steps before we can
> > proceed with the probe:
> >
> > - Issue Read SFDP in 8D mode and see if we get the "SFDP" signature
> >   correctly. If we don't, exit.
> >
> > - Read BFPT in 8D mode, and see if Soft Reset is supported.
> >
> > - If it is, issue a soft reset and go on as usual. If it isn't, error
> >   out, and the probe fails.
> >
> > The problem is, I'm not sure if controllers will be okay doing this on a
> > flash that is in 1S mode. Say the controller expects the DQS line to
> > toggle when the flash is sending data. Now, we tell the controller we
> > will read 16 bytes (SFDP header), but since the flash is in 1S mode, it
> > sees some other command and might not send out any data at all. In this
> > case, will the controller hang, waiting forever for the flash to toggle
> > DQS?
> >
> > FWIW, the controller on our board (Cadence QSPI) doesn't hang. But I'm
> > not sure how other controllers would react. That's why I went with the
> > more minimal option. The soft reset sequence doesn't expect to receive
> > any data. It only sends it.
> 
> So, we never sure if another controller (other than cadence) can
> guarantee to toggle the DQS? Can't the flash wait till to controller
> to toggle? I would like to see how this implemented in Linux, is it
> under progress or done in similar way?

DQS is just an example of something that can go wrong. The point I'm 
trying to make here is that since we don't know what state the flash is 
in, we might be issuing it commands in a different mode. Something like 
that can go wrong in many places, so we want to do as little as 
possible. That is why I hid this behind a config so people who don't 
need this don't have to bother with the trouble.

The soft reset sequence sends out 2 bytes and that's it. Detecting it 
via SFDP involves reading SFDP in 8D mode. It is much more complicated, 
and so much more can go wrong.

We are trying to solve an impossible problem here: cleanly handling 
flashes booting in stateful mode (I wrote about it here [0]). IMHO we 
should be trying to get away with as little as we can.

Linux's stance on this problem is that "bootloaders should hand us the 
flash in 1S mode. We don't want to deal with this problem as of now." 
Someone somewhere has to do this. Right now, that burden falls on the 
bootloader.
 
[0] https://lore.kernel.org/linux-mtd/20200228093658.zc3uifqg4zruokq3 at ti.com/
diff mbox series

Patch

diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 018e8c597e..38d509c568 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -88,6 +88,17 @@  config SPI_FLASH_SFDP_SUPPORT
 	 SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
 	 tables as per JESD216 standard.
 
+config SPI_FLASH_SOFT_RESET
+	bool "Software Reset support for SPI NOR flashes"
+	help
+	 Enable support for xSPI Software Reset. It will be used to switch
+	 from Octal DTR mode to legacy mode to allow detecting flashes that
+	 are handed to us in Octal DTR mode. It is expected that if the config
+	 is enabled the flash supports the Soft Reset sequence and is booted in
+	 Octal DTR mode. Do not enable this config on flashes that are not
+	 supposed to be handed to U-Boot in Octal DTR mode, even if they _do_
+	 support the Soft Reset sequence.
+
 config SPI_FLASH_BAR
 	bool "SPI flash Bank/Extended address register support"
 	help
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 52b3775035..3af2c6afa9 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -2922,6 +2922,33 @@  int spi_nor_scan(struct spi_nor *nor)
 
 	nor->setup = spi_nor_default_setup;
 
+#if defined(CONFIG_SPI_FLASH_SOFT_RESET)
+	/*
+	 * When the flash is handed to us in a stateful mode like 8D-8D-8D, it
+	 * is difficult to detect the mode the flash is in. One option is to
+	 * read SFDP in all modes and see which one gives the correct "SFDP"
+	 * signature, but not all flashes support SFDP in 8D-8D-8D mode.
+	 *
+	 * Further, even if you detect the mode of the flash via SFDP, you
+	 * still have the problem of actually reading the ID. The Read ID
+	 * command is not standardized across flash vendors. Flashes can have
+	 * different dummy cycles needed for reading the ID. Some flashes even
+	 * expect a 4-byte dummy address with the Read ID command. All this
+	 * information cannot be obtained from the SFDP table.
+	 *
+	 * So, perform a Software Reset sequence before reading the ID and
+	 * initializing the flash. A Soft Reset will bring back the flash in
+	 * its default protocol mode assuming no non-volatile configuration was
+	 * set. This will let us detect the flash even if ROM hands it to us in
+	 * Octal DTR mode.
+	 *
+	 * To accommodate cases where there is more than one flash on a board,
+	 * and only one of them needs a soft reset, failure to reset is not
+	 * made fatal, and we still try to read ID if possible.
+	 */
+	spi_nor_soft_reset(nor);
+#endif /* CONFIG_SPI_FLASH_SOFT_RESET */
+
 	info = spi_nor_read_id(nor);
 	if (IS_ERR_OR_NULL(info))
 		return -ENOENT;