[U-Boot] QSPI support on i.MX7D Sabre Eval Board
Thomas Schaefer
Thomas.Schaefer at kontron.com
Wed Jun 19 16:10:52 UTC 2019
Hi Fabio,
> Hi Thomas,
>
> On Wed, Jun 19, 2019 at 10:04 AM Thomas Schaefer <Thomas.Schaefer at kontron.com> wrote:
> >
> > Hi all,
> >
> > I've built current u-boot (v2019.07-rc4) with QSPI support for our i.MX7D Sabre eval system. I am using mx7dsabresd_qspi_defconfig.
> >
> > The resulting u-boot fails to read from QSPI, i.e. the data read is not the same than that written before with a previous (v2018) version.
> >
> > After some investigation I found that the 'is_controller_busy' function comes back with -ETIMEDOUT during read operation, because the retry count >of 5 is too low.
> >
> > To figure out how many retries are needed, I added some debug code as part of a while(1) loop to the is_controller_busy function:
> >
> > diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index
> > 1598c4f698..fa5b7a29f2 100644
> > --- a/drivers/spi/fsl_qspi.c
> > +++ b/drivers/spi/fsl_qspi.c
> > @@ -152,16 +152,20 @@ static inline int is_controller_busy(const struct fsl_qspi_priv *priv)
> > u32 val;
> > const u32 mask = QSPI_SR_BUSY_MASK | QSPI_SR_AHB_ACC_MASK |
> > QSPI_SR_IP_ACC_MASK;
> > - unsigned int retry = 5;
> > + unsigned int retry = 0;
> >
> > do {
> > val = qspi_read32(priv->flags, &priv->regs->sr);
> >
> > - if ((~val & mask) == mask)
> > + if ((~val & mask) == mask) {
> > + if (retry > 5)
> > + printf("%s: timeout! retry = %d\n",
> > + __func__, retry);
> > return 0;
> > + }
> >
> > udelay(1);
> > - } while (--retry);
> > + retry++;
> > + } while (1);
> >
> > return -ETIMEDOUT;
> > }
> >
> > On my MX7 eval system I found that a retry count between 73 and 147 is necessary to make sure that the controller will be ready before the next operation.
> >
> > So from my point of view we have 2 options to fix this issue:
> >
> > - increase retry from 5 to 200
> > - wait in an endless loop (while (1) ) and return only when the controller is ready (which means that the board will hang if the controller doesn't come back for some other reason.
> >
> > What do you think?
>
> I think that readl_poll_timeout() could be used here as it will timeout if the QSPI controller is not ready.
>
> Also, could you check how this is handled in the fsl qspi driver in the kernel?
There is a similar readl_plll_tout call in 5.1.12 linux kernel driver (spi-fsl-qspi.c) with 1000us timeout:
/* wait for the controller being ready */
fsl_qspi_readl_poll_tout(q, base + QUADSPI_SR, (QUADSPI_SR_IP_ACC_MASK |
QUADSPI_SR_AHB_ACC_MASK), 10, 1000);
The fsl additions take concern about endianess before calling the general 'readl_poll_timeout' function.
Thomas
More information about the U-Boot
mailing list