[PATCH v4 2/4] mtd: spi-nor-core: Adding different type of command extension in Soft Reset

liao jaime jaimeliao.tw at gmail.com
Tue Oct 26 09:03:54 CEST 2021


>
> On 25/10/21 12:30PM, Jagan Teki wrote:
> > On Mon, Oct 18, 2021 at 11:54 AM JaimeLiao <jaimeliao.tw at gmail.com> wrote:
> > >
> > > Power-on-Reset is a method to restore flash back to 1S-1S-1S mode from 8D-8D-8D
> > > in the begging of probe.
> > >
> > > Command extension type is not standardized across flash vendors in DTR mode.
> > >
> > > For suiting different vendor flash devices, adding a flag to seperate types for
> > > soft reset on boot.
> > >
> > > Signed-off-by: JaimeLiao <jaimeliao.tw at gmail.com>
> > > ---
> > >  drivers/mtd/spi/Kconfig        | 7 +++++++
> > >  drivers/mtd/spi/spi-nor-core.c | 7 ++++++-
> > >  2 files changed, 13 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
> > > index 67599b32c9..8304d6c973 100644
> > > --- a/drivers/mtd/spi/Kconfig
> > > +++ b/drivers/mtd/spi/Kconfig
> > > @@ -97,6 +97,13 @@ config SPI_FLASH_SMART_HWCAPS
> > >          can support a type of operation in a much more refined way compared
> > >          to using flags like SPI_RX_DUAL, SPI_TX_QUAD, etc.
> > >
> > > +config SPI_NOR_BOOT_SOFT_RESET_EXT_INVERT
> > > +       bool "Command extension type is INVERT for Software Reset on boot"
> > > +       default n
> > > +       help
> > > +        Because of SFDP information can not be get before boot.
> > > +        So define command extension type is INVERT when Software Reset on boot only.
> > > +
> > >  config SPI_FLASH_SOFT_RESET
> > >         bool "Software Reset support for SPI NOR flashes"
> > >         default n
> > > diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
> > > index fdaca0a0d3..87a7de7d60 100644
> > > --- a/drivers/mtd/spi/spi-nor-core.c
> > > +++ b/drivers/mtd/spi/spi-nor-core.c
> > > @@ -3661,7 +3661,12 @@ static int spi_nor_soft_reset(struct spi_nor *nor)
> > >         enum spi_nor_cmd_ext ext;
> > >
> > >         ext = nor->cmd_ext_type;
> > > -       nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;
> > > +       if (nor->cmd_ext_type == SPI_NOR_EXT_NONE) {
> > > +               nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;
> > > +#if CONFIG_IS_ENABLED(SPI_NOR_BOOT_SOFT_RESET_EXT_INVERT)
> > > +               nor->cmd_ext_type = SPI_NOR_EXT_INVERT;
> > > +#endif /* SPI_NOR_BOOT_SOFT_RESET_EXT_INVERT */
> >
> > I think we can get the SPI_NOR_EXT_INVERT by parsing bfpt, can you try
> > it that way instead of new macro?
>
> The problem is that for OSPI boot mode the ROM can often leave the flash
> in 8D-8D-8D mode. So when U-Boot first starts executing the flash is
> already in 8D-8D-8D mode and there is no easy and reliable way to detect
> this mode. So we must blindly perform a soft reset before probing the
> flash and reading SFDP so that it is reset back to a usable state.
>
> This is why we can't detect the extension via BFPT since the flash is in
> an unknown state. This is not the case when resetting before booting the
> OS since at that point we have fully probed the flash. So I think this
> config must only be used for the reset at boot time. For later resets we
> should indeed use the extension provided by BFPT.
>
> This is a kinda hacky but I can't come up with a better alternative.
>
> Jamie,
>
> Below diff is what I have been suggesting you in my earlier replies.
> Note that this is just a quick and dirty implementation, I have not
> tested this at all. That is up to you to do. Please also test soft reset
> _after_ the probe is finished so we know that it works correctly when
> using data from BFPT as well.
>
> -- 8< --
> diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
> index 4388a08a90..b0f22e0ce5 100644
> --- a/drivers/mtd/spi/spi-nor-core.c
> +++ b/drivers/mtd/spi/spi-nor-core.c
> @@ -3616,10 +3616,6 @@ static int spi_nor_soft_reset(struct spi_nor *nor)
>  {
>         struct spi_mem_op op;
>         int ret;
> -       enum spi_nor_cmd_ext ext;
> -
> -       ext = nor->cmd_ext_type;
> -       nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;
>
>         op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_SRSTEN, 0),
>                         SPI_MEM_OP_NO_DUMMY,
> @@ -3629,7 +3625,7 @@ static int spi_nor_soft_reset(struct spi_nor *nor)
>         ret = spi_mem_exec_op(nor->spi, &op);
>         if (ret) {
>                 dev_warn(nor->dev, "Software reset enable failed: %d\n", ret);
> -               goto out;
> +               return ret;
>         }
>
>         op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_SRST, 0),
> @@ -3640,7 +3636,7 @@ static int spi_nor_soft_reset(struct spi_nor *nor)
>         ret = spi_mem_exec_op(nor->spi, &op);
>         if (ret) {
>                 dev_warn(nor->dev, "Software reset failed: %d\n", ret);
> -               goto out;
> +               return ret;
>         }
>
>         /*
> @@ -3650,9 +3646,7 @@ static int spi_nor_soft_reset(struct spi_nor *nor)
>          */
>         udelay(SPI_NOR_SRST_SLEEP_LEN);
>
> -out:
> -       nor->cmd_ext_type = ext;
> -       return ret;
> +       return 0;
>  }
>  #endif /* CONFIG_SPI_FLASH_SOFT_RESET */
>
> @@ -3698,6 +3692,44 @@ void spi_nor_set_fixups(struct spi_nor *nor)
>  #endif
>  }
>
> +/*
> + * 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.
> + */
> +static void spi_nor_soft_reset_on_boot(struct spi_nor *nor)
> +{
> +       enum spi_nor_cmd_ext ext;
> +
> +       ext = nor->cmd_ext_type;
> +
> +       if (CONFIG_IS_ENABLED(SPI_NOR_BOOT_SOFT_RESET_EXT_INVERT))
> +               nor->cmd_ext_type = SPI_NOR_EXT_INVERT;
> +       else
> +               nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;
> +
> +       spi_nor_soft_reset(nor);
> +
> +       nor->cmd_ext_type = ext;
> +}
> +
>  int spi_nor_scan(struct spi_nor *nor)
>  {
>         struct spi_nor_flash_parameter params;
> @@ -3722,32 +3754,8 @@ int spi_nor_scan(struct spi_nor *nor)
>
>         nor->setup = spi_nor_default_setup;
>
> -#ifdef CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT
> -       /*
> -        * 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_ON_BOOT */
> +       if (CONFIG_IS_ENABLED(SPI_FLASH_SOFT_RESET_ON_BOOT))
> +               spi_nor_soft_reset_on_boot(nor);
>
>         info = spi_nor_read_id(nor);
>         if (IS_ERR_OR_NULL(info))
>
> --

For validating soft_reset after probe, I have test it on my side.
It is working with command extension type which got from BFPT.

> Regards,
> Pratyush Yadav
> Texas Instruments Inc.


More information about the U-Boot mailing list