public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] Fix read error in fsl_qspi driver
@ 2019-07-01 15:37 Thomas Schaefer
  2019-07-01 15:37 ` [U-Boot] [PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout Thomas Schaefer
  2019-07-01 15:37 ` [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation Thomas Schaefer
  0 siblings, 2 replies; 9+ messages in thread
From: Thomas Schaefer @ 2019-07-01 15:37 UTC (permalink / raw)
  To: u-boot

Hi all,

The following patchset will fix QSPI flash read error discovered on i.MX7D
Sabre eval system. Could you please check and apply to upcoming v2019.07
release?

Best regards,
Thomas Schaefer

[PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout
[PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation

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

* [U-Boot] [PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout
  2019-07-01 15:37 [U-Boot] Fix read error in fsl_qspi driver Thomas Schaefer
@ 2019-07-01 15:37 ` Thomas Schaefer
  2019-07-01 15:40   ` Fabio Estevam
  2019-07-02 11:01   ` Jagan Teki
  2019-07-01 15:37 ` [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation Thomas Schaefer
  1 sibling, 2 replies; 9+ messages in thread
From: Thomas Schaefer @ 2019-07-01 15:37 UTC (permalink / raw)
  To: u-boot

During QSPI reads, current is_controller_busy function sporadically
fails with -ETIMEDOUT due to fixed number of 5 test loops. Using
timer functions to wait 1000 us instead will fix this.

Signed-off-by: Thomas Schaefer <thomas.schaefer@kontron.com>
---
 drivers/spi/fsl_qspi.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 1598c4f698..2c5937509f 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -152,7 +152,7 @@ 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 long timeout = timer_get_us() + 1000;
 
 	do {
 		val = qspi_read32(priv->flags, &priv->regs->sr);
@@ -160,10 +160,9 @@ static inline int is_controller_busy(const struct fsl_qspi_priv *priv)
 		if ((~val & mask) == mask)
 			return 0;
 
-		udelay(1);
-	} while (--retry);
-
-	return -ETIMEDOUT;
+		if (timer_get_us() > timeout )
+			return -ETIMEDOUT;
+	} while (1);
 }
 
 /* QSPI support swapping the flash read/write data
-- 
2.11.0

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

* [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation
  2019-07-01 15:37 [U-Boot] Fix read error in fsl_qspi driver Thomas Schaefer
  2019-07-01 15:37 ` [U-Boot] [PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout Thomas Schaefer
@ 2019-07-01 15:37 ` Thomas Schaefer
  2019-07-01 15:41   ` Fabio Estevam
  2019-07-02 11:11   ` Jagan Teki
  1 sibling, 2 replies; 9+ messages in thread
From: Thomas Schaefer @ 2019-07-01 15:37 UTC (permalink / raw)
  To: u-boot

Use readl_poll_timeout instead of explicit calculation

Signed-off-by: Thomas Schaefer <thomas.schaefer@kontron.com>
---
 drivers/spi/fsl_qspi.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 2c5937509f..41abe1996f 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -10,6 +10,7 @@
 #include <spi.h>
 #include <asm/io.h>
 #include <linux/sizes.h>
+#include <linux/iopoll.h>
 #include <dm.h>
 #include <errno.h>
 #include <watchdog.h>
@@ -150,19 +151,13 @@ static void qspi_write32(u32 flags, u32 *addr, u32 val)
 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 long timeout = timer_get_us() + 1000;
+	u32 mask = QSPI_SR_BUSY_MASK | QSPI_SR_AHB_ACC_MASK |
+		   QSPI_SR_IP_ACC_MASK;
 
-	do {
-		val = qspi_read32(priv->flags, &priv->regs->sr);
+	if (priv->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG)
+		mask = (u32)cpu_to_be32(mask);
 
-		if ((~val & mask) == mask)
-			return 0;
-
-		if (timer_get_us() > timeout )
-			return -ETIMEDOUT;
-	} while (1);
+	return readl_poll_timeout(&priv->regs->sr, val, !(val & mask), 1000);
 }
 
 /* QSPI support swapping the flash read/write data
-- 
2.11.0

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

* [U-Boot] [PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout
  2019-07-01 15:37 ` [U-Boot] [PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout Thomas Schaefer
@ 2019-07-01 15:40   ` Fabio Estevam
  2019-07-02 11:01   ` Jagan Teki
  1 sibling, 0 replies; 9+ messages in thread
From: Fabio Estevam @ 2019-07-01 15:40 UTC (permalink / raw)
  To: u-boot

On Mon, Jul 1, 2019 at 12:38 PM Thomas Schaefer
<thomas.schaefer@kontron.com> wrote:
>
> During QSPI reads, current is_controller_busy function sporadically
> fails with -ETIMEDOUT due to fixed number of 5 test loops. Using
> timer functions to wait 1000 us instead will fix this.
>
> Signed-off-by: Thomas Schaefer <thomas.schaefer@kontron.com>

Thanks for the fix:

Reviewed-by: Fabio Estevam <festevam@gmail.com>

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

* [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation
  2019-07-01 15:37 ` [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation Thomas Schaefer
@ 2019-07-01 15:41   ` Fabio Estevam
  2019-07-02 11:11   ` Jagan Teki
  1 sibling, 0 replies; 9+ messages in thread
From: Fabio Estevam @ 2019-07-01 15:41 UTC (permalink / raw)
  To: u-boot

On Mon, Jul 1, 2019 at 12:37 PM Thomas Schaefer
<thomas.schaefer@kontron.com> wrote:
>
> Use readl_poll_timeout instead of explicit calculation
>
> Signed-off-by: Thomas Schaefer <thomas.schaefer@kontron.com>

Reviewed-by: Fabio Estevam <festevam@gmail.com>

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

* [U-Boot] [PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout
  2019-07-01 15:37 ` [U-Boot] [PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout Thomas Schaefer
  2019-07-01 15:40   ` Fabio Estevam
@ 2019-07-02 11:01   ` Jagan Teki
  1 sibling, 0 replies; 9+ messages in thread
From: Jagan Teki @ 2019-07-02 11:01 UTC (permalink / raw)
  To: u-boot

On Mon, Jul 1, 2019 at 9:08 PM Thomas Schaefer
<thomas.schaefer@kontron.com> wrote:
>
> During QSPI reads, current is_controller_busy function sporadically
> fails with -ETIMEDOUT due to fixed number of 5 test loops. Using
> timer functions to wait 1000 us instead will fix this.
>
> Signed-off-by: Thomas Schaefer <thomas.schaefer@kontron.com>
> ---

Applied to u-boot-spi/master

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

* [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation
  2019-07-01 15:37 ` [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation Thomas Schaefer
  2019-07-01 15:41   ` Fabio Estevam
@ 2019-07-02 11:11   ` Jagan Teki
  2019-07-02 11:43     ` Thomas Schaefer
  1 sibling, 1 reply; 9+ messages in thread
From: Jagan Teki @ 2019-07-02 11:11 UTC (permalink / raw)
  To: u-boot

On Mon, Jul 1, 2019 at 9:07 PM Thomas Schaefer
<thomas.schaefer@kontron.com> wrote:
>
> Use readl_poll_timeout instead of explicit calculation
>
> Signed-off-by: Thomas Schaefer <thomas.schaefer@kontron.com>
> ---
>  drivers/spi/fsl_qspi.c | 17 ++++++-----------
>  1 file changed, 6 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
> index 2c5937509f..41abe1996f 100644
> --- a/drivers/spi/fsl_qspi.c
> +++ b/drivers/spi/fsl_qspi.c
> @@ -10,6 +10,7 @@
>  #include <spi.h>
>  #include <asm/io.h>
>  #include <linux/sizes.h>
> +#include <linux/iopoll.h>
>  #include <dm.h>
>  #include <errno.h>
>  #include <watchdog.h>
> @@ -150,19 +151,13 @@ static void qspi_write32(u32 flags, u32 *addr, u32 val)
>  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 long timeout = timer_get_us() + 1000;
> +       u32 mask = QSPI_SR_BUSY_MASK | QSPI_SR_AHB_ACC_MASK |
> +                  QSPI_SR_IP_ACC_MASK;
>
> -       do {
> -               val = qspi_read32(priv->flags, &priv->regs->sr);
> +       if (priv->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG)
> +               mask = (u32)cpu_to_be32(mask);

This look like a BE check, which was not there before isn't it?

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

* [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation
  2019-07-02 11:11   ` Jagan Teki
@ 2019-07-02 11:43     ` Thomas Schaefer
  2019-07-03  8:40       ` Jagan Teki
  0 siblings, 1 reply; 9+ messages in thread
From: Thomas Schaefer @ 2019-07-02 11:43 UTC (permalink / raw)
  To: u-boot

> Von: Jagan Teki <jagan@amarulasolutions.com> 
> Gesendet: Dienstag, 2. Juli 2019 13:12
> 
> On Mon, Jul 1, 2019 at 9:07 PM Thomas Schaefer <thomas.schaefer@kontron.com> wrote:
> >
> > Use readl_poll_timeout instead of explicit calculation
> >
> > Signed-off-by: Thomas Schaefer <thomas.schaefer@kontron.com>
> > ---
> >  drivers/spi/fsl_qspi.c | 17 ++++++-----------
> >  1 file changed, 6 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index 
> > 2c5937509f..41abe1996f 100644
> > --- a/drivers/spi/fsl_qspi.c
> > +++ b/drivers/spi/fsl_qspi.c
> > @@ -10,6 +10,7 @@
> >  #include <spi.h>
> >  #include <asm/io.h>
> >  #include <linux/sizes.h>
> > +#include <linux/iopoll.h>
> >  #include <dm.h>
> >  #include <errno.h>
> >  #include <watchdog.h>
> > @@ -150,19 +151,13 @@ static void qspi_write32(u32 flags, u32 *addr, 
> > u32 val)  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 long timeout = timer_get_us() + 1000;
> > +       u32 mask = QSPI_SR_BUSY_MASK | QSPI_SR_AHB_ACC_MASK |
> > +                  QSPI_SR_IP_ACC_MASK;
> >
> > -       do {
> > -               val = qspi_read32(priv->flags, &priv->regs->sr);
> > +       if (priv->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG)
> > +               mask = (u32)cpu_to_be32(mask);
> 
> This look like a BE check, which was not there before isn't it?
> 

Hi Jagan,

The previous implementation was using the qspi_read32 function, that
implemented this endianess checking. As the readl_poll_timeout macro finally
ends with

#define __arch_getl(a)  (*(volatile unsigned int *)(a))

in arch/arm/include/asm/io.h. When swapping the 'mask' in case of BE, the
result is the same as when using qspi_read32 before.

However, I did not test this as the QSPI_FLAG_REGMAP_ENDIAN_BIG is not set
on i.MX7 systems.

Also I found that current linux kernel does this BE check (negated LE check)
with the 'mask' variable in drivers/spi/spi-fsl-qspi.c

if (!q->devtype_data->little_endian)
    mask = (u32)cpu_to_be32(mask);

Best reards,
Thomas

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

* [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation
  2019-07-02 11:43     ` Thomas Schaefer
@ 2019-07-03  8:40       ` Jagan Teki
  0 siblings, 0 replies; 9+ messages in thread
From: Jagan Teki @ 2019-07-03  8:40 UTC (permalink / raw)
  To: u-boot

On Tue, Jul 2, 2019 at 5:13 PM Thomas Schaefer
<Thomas.Schaefer@kontron.com> wrote:
>
> > Von: Jagan Teki <jagan@amarulasolutions.com>
> > Gesendet: Dienstag, 2. Juli 2019 13:12
> >
> > On Mon, Jul 1, 2019 at 9:07 PM Thomas Schaefer <thomas.schaefer@kontron.com> wrote:
> > >
> > > Use readl_poll_timeout instead of explicit calculation
> > >
> > > Signed-off-by: Thomas Schaefer <thomas.schaefer@kontron.com>
> > > ---
> > >  drivers/spi/fsl_qspi.c | 17 ++++++-----------
> > >  1 file changed, 6 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index
> > > 2c5937509f..41abe1996f 100644
> > > --- a/drivers/spi/fsl_qspi.c
> > > +++ b/drivers/spi/fsl_qspi.c
> > > @@ -10,6 +10,7 @@
> > >  #include <spi.h>
> > >  #include <asm/io.h>
> > >  #include <linux/sizes.h>
> > > +#include <linux/iopoll.h>
> > >  #include <dm.h>
> > >  #include <errno.h>
> > >  #include <watchdog.h>
> > > @@ -150,19 +151,13 @@ static void qspi_write32(u32 flags, u32 *addr,
> > > u32 val)  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 long timeout = timer_get_us() + 1000;
> > > +       u32 mask = QSPI_SR_BUSY_MASK | QSPI_SR_AHB_ACC_MASK |
> > > +                  QSPI_SR_IP_ACC_MASK;
> > >
> > > -       do {
> > > -               val = qspi_read32(priv->flags, &priv->regs->sr);
> > > +       if (priv->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG)
> > > +               mask = (u32)cpu_to_be32(mask);
> >
> > This look like a BE check, which was not there before isn't it?
> >
>
> Hi Jagan,
>
> The previous implementation was using the qspi_read32 function, that
> implemented this endianess checking. As the readl_poll_timeout macro finally
> ends with
>
> #define __arch_getl(a)  (*(volatile unsigned int *)(a))
>
> in arch/arm/include/asm/io.h. When swapping the 'mask' in case of BE, the
> result is the same as when using qspi_read32 before.

Okay, it was supported before. thanks for the clarity.

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

end of thread, other threads:[~2019-07-03  8:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-07-01 15:37 [U-Boot] Fix read error in fsl_qspi driver Thomas Schaefer
2019-07-01 15:37 ` [U-Boot] [PATCH 1/2] drivers/spi: fsl_qspi: fix read timeout Thomas Schaefer
2019-07-01 15:40   ` Fabio Estevam
2019-07-02 11:01   ` Jagan Teki
2019-07-01 15:37 ` [U-Boot] [PATCH 2/2] drivers/spi: fsl_qspi: improve timeout calculation Thomas Schaefer
2019-07-01 15:41   ` Fabio Estevam
2019-07-02 11:11   ` Jagan Teki
2019-07-02 11:43     ` Thomas Schaefer
2019-07-03  8:40       ` Jagan Teki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox