diff mbox series

[2/2] spi: nxp_fspi: Implement errata workaround for LS1028A

Message ID 20210322063012.3995485-2-kuldeep.singh@nxp.com
State Superseded
Delegated to: Stefano Babic
Headers show
Series [1/2] spi: nxp-fspi: Add support for IP read only | expand

Commit Message

Kuldeep Singh March 22, 2021, 6:30 a.m. UTC
Errata ERR050568 description says that "Flash access by FlexSPI AHB
command may not work with platform frequency equal to 300 MHz" on
LS1028A.

By default, smaller length reads(equal to RX FIFO size) are done by IP
bus and larger length reads using AHB bus. For adding errata workaround,
use IP bus to read entire flash contents and disable AHB path when
platform frequency is 300Mhz.

Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
---
 drivers/spi/nxp_fspi.c | 49 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 5 deletions(-)

Comments

Kuldeep Singh March 22, 2021, 6:35 a.m. UTC | #1
+ Ye Li

> -----Original Message-----
> From: Kuldeep Singh <kuldeep.singh@nxp.com>
> Sent: Monday, March 22, 2021 12:00 PM
> To: Jagan Teki <jagan@amarulasolutions.com>; u-boot@lists.denx.de
> Cc: Kuldeep Singh <kuldeep.singh@nxp.com>
> Subject: [PATCH 2/2] spi: nxp_fspi: Implement errata workaround for LS1028A
> 
> Errata ERR050568 description says that "Flash access by FlexSPI AHB
> command may not work with platform frequency equal to 300 MHz" on
> LS1028A.
> 
> By default, smaller length reads(equal to RX FIFO size) are done by IP bus and
> larger length reads using AHB bus. For adding errata workaround, use IP bus
> to read entire flash contents and disable AHB path when platform frequency
> is 300Mhz.
> 
> Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>

Hi Ye,
Please confirm and let me know if this patch breaks imx platforms.

Regards
Kuldeep
> ---
>  drivers/spi/nxp_fspi.c | 49 +++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 44 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/spi/nxp_fspi.c b/drivers/spi/nxp_fspi.c index
> e1b3d2d77b..7ba3a72223 100644
> --- a/drivers/spi/nxp_fspi.c
> +++ b/drivers/spi/nxp_fspi.c
> @@ -41,6 +41,11 @@
>  #include <spi.h>
>  #include <spi-mem.h>
>  #include <asm/io.h>
> +#ifdef CONFIG_FSL_LAYERSCAPE
> +#include <asm/arch/clock.h>
> +#include <asm/arch/soc.h>
> +#include <asm/arch/speed.h>
> +#endif
>  #include <linux/bitops.h>
>  #include <linux/kernel.h>
>  #include <linux/sizes.h>
> @@ -315,7 +320,7 @@ struct nxp_fspi_devtype_data {
>  	bool little_endian;
>  };
> 
> -static const struct nxp_fspi_devtype_data lx2160a_data = {
> +static struct nxp_fspi_devtype_data lx2160a_data = {
>  	.rxfifo = SZ_512,       /* (64  * 64 bits)  */
>  	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
>  	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */ @@ -323,7 +328,7 @@
> static const struct nxp_fspi_devtype_data lx2160a_data = {
>  	.little_endian = true,  /* little-endian    */
>  };
> 
> -static const struct nxp_fspi_devtype_data imx8mm_data = {
> +static struct nxp_fspi_devtype_data imx8mm_data = {
>  	.rxfifo = SZ_512,       /* (64  * 64 bits)  */
>  	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
>  	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */ @@ -338,7 +343,7 @@
> struct nxp_fspi {
>  	u32 memmap_phy;
>  	u32 memmap_phy_size;
>  	struct clk clk, clk_en;
> -	const struct nxp_fspi_devtype_data *devtype_data;
> +	struct nxp_fspi_devtype_data *devtype_data;
>  };
> 
>  static inline int needs_ip_only(struct nxp_fspi *f) @@ -529,8 +534,8 @@
> static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
>  	for (i = 0; i < ARRAY_SIZE(lutval); i++)
>  		fspi_writel(f, lutval[i], base + FSPI_LUT_REG(i));
> 
> -	dev_dbg(f->dev, "CMD[%x] lutval[0:%x \t 1:%x \t 2:%x \t 3:%x]\n",
> -		op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3]);
> +	dev_dbg(f->dev, "CMD[%x] lutval[0:%x \t 1:%x \t 2:%x \t 3:%x], size:
> 0x%08x\n",
> +		op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3],
> +op->data.nbytes);
> 
>  	/* lock LUT */
>  	fspi_writel(f, FSPI_LUTKEY_VALUE, f->iobase + FSPI_LUTKEY); @@ -
> 827,6 +832,31 @@ static int nxp_fspi_adjust_op_size(struct spi_slave *slave,
>  	return 0;
>  }
> 
> +static void erratum_err050568(struct nxp_fspi *f) {
> +	struct sys_info sysinfo;
> +	u32 svr = 0, freq = 0;
> +
> +	/* Check for LS1028A variants */
> +	svr = SVR_SOC_VER(get_svr());
> +	if (svr != SVR_LS1017A ||
> +	    svr != SVR_LS1018A ||
> +	    svr != SVR_LS1027A ||
> +	    svr != SVR_LS1028A) {
> +		dev_dbg(f->dev, "Errata applicable only for LS1028A
> variants\n");
> +		return;
> +	}
> +
> +	/* Read PLL frequency */
> +	get_sys_info(&sysinfo);
> +	freq = sysinfo.freq_systembus / 1000000; /* Convert to MHz */
> +	dev_dbg(f->dev, "svr: %08x, Frequency: %dMhz\n", svr, freq);
> +
> +	/* Use IP bus only if PLL is 300MHz */
> +	if (freq == 300)
> +		f->devtype_data->quirks |= FSPI_QUIRK_USE_IP_ONLY; }
> +
>  static int nxp_fspi_default_setup(struct nxp_fspi *f)  {
>  	void __iomem *base = f->iobase;
> @@ -847,6 +877,15 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f)
>  		return ret;
>  #endif
> 
> +	/*
> +	 * ERR050568: Flash access by FlexSPI AHB command may not work
> with
> +	 * platform frequency equal to 300 MHz on LS1028A.
> +	 * LS1028A reuses LX2160A compatible entry. Make errata applicable
> for
> +	 * Layerscape LS1028A platform family.
> +	 */
> +	if (device_is_compatible(f->dev, "nxp,lx2160a-fspi"))
> +		erratum_err050568(f);
> +
>  	/* Reset the module */
>  	/* w1c register, wait unit clear */
>  	ret = fspi_readl_poll_tout(f, f->iobase + FSPI_MCR0,
> --
> 2.25.1
Jagan Teki April 19, 2021, 6:47 a.m. UTC | #2
On Mon, Mar 22, 2021 at 12:00 PM Kuldeep Singh <kuldeep.singh@nxp.com> wrote:
>
> Errata ERR050568 description says that "Flash access by FlexSPI AHB
> command may not work with platform frequency equal to 300 MHz" on
> LS1028A.
>
> By default, smaller length reads(equal to RX FIFO size) are done by IP
> bus and larger length reads using AHB bus. For adding errata workaround,
> use IP bus to read entire flash contents and disable AHB path when
> platform frequency is 300Mhz.
>
> Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
> ---

Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
Kuldeep Singh June 17, 2021, 5:15 a.m. UTC | #3
Hi Stefano,

> -----Original Message-----
> From: Jagan Teki <jagan@amarulasolutions.com>
> Sent: Monday, April 19, 2021 12:17 PM
> To: Kuldeep Singh <kuldeep.singh@nxp.com>
> Cc: U-Boot-Denx <u-boot@lists.denx.de>
> Subject: [EXT] Re: [PATCH 2/2] spi: nxp_fspi: Implement errata workaround for
> LS1028A
> 
> Caution: EXT Email
> 
> On Mon, Mar 22, 2021 at 12:00 PM Kuldeep Singh <kuldeep.singh@nxp.com>
> wrote:
> >
> > Errata ERR050568 description says that "Flash access by FlexSPI AHB
> > command may not work with platform frequency equal to 300 MHz" on
> > LS1028A.
> >
> > By default, smaller length reads(equal to RX FIFO size) are done by IP
> > bus and larger length reads using AHB bus. For adding errata
> > workaround, use IP bus to read entire flash contents and disable AHB
> > path when platform frequency is 300Mhz.
> >
> > Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
> > ---
> 
> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>

Jagan has reviewed and assigned this patch series[1] to you.
Could you please help in reviewing it.

Thanks
Kuldeep
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=235180
diff mbox series

Patch

diff --git a/drivers/spi/nxp_fspi.c b/drivers/spi/nxp_fspi.c
index e1b3d2d77b..7ba3a72223 100644
--- a/drivers/spi/nxp_fspi.c
+++ b/drivers/spi/nxp_fspi.c
@@ -41,6 +41,11 @@ 
 #include <spi.h>
 #include <spi-mem.h>
 #include <asm/io.h>
+#ifdef CONFIG_FSL_LAYERSCAPE
+#include <asm/arch/clock.h>
+#include <asm/arch/soc.h>
+#include <asm/arch/speed.h>
+#endif
 #include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/sizes.h>
@@ -315,7 +320,7 @@  struct nxp_fspi_devtype_data {
 	bool little_endian;
 };
 
-static const struct nxp_fspi_devtype_data lx2160a_data = {
+static struct nxp_fspi_devtype_data lx2160a_data = {
 	.rxfifo = SZ_512,       /* (64  * 64 bits)  */
 	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
 	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
@@ -323,7 +328,7 @@  static const struct nxp_fspi_devtype_data lx2160a_data = {
 	.little_endian = true,  /* little-endian    */
 };
 
-static const struct nxp_fspi_devtype_data imx8mm_data = {
+static struct nxp_fspi_devtype_data imx8mm_data = {
 	.rxfifo = SZ_512,       /* (64  * 64 bits)  */
 	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
 	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
@@ -338,7 +343,7 @@  struct nxp_fspi {
 	u32 memmap_phy;
 	u32 memmap_phy_size;
 	struct clk clk, clk_en;
-	const struct nxp_fspi_devtype_data *devtype_data;
+	struct nxp_fspi_devtype_data *devtype_data;
 };
 
 static inline int needs_ip_only(struct nxp_fspi *f)
@@ -529,8 +534,8 @@  static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
 	for (i = 0; i < ARRAY_SIZE(lutval); i++)
 		fspi_writel(f, lutval[i], base + FSPI_LUT_REG(i));
 
-	dev_dbg(f->dev, "CMD[%x] lutval[0:%x \t 1:%x \t 2:%x \t 3:%x]\n",
-		op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3]);
+	dev_dbg(f->dev, "CMD[%x] lutval[0:%x \t 1:%x \t 2:%x \t 3:%x], size: 0x%08x\n",
+		op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3], op->data.nbytes);
 
 	/* lock LUT */
 	fspi_writel(f, FSPI_LUTKEY_VALUE, f->iobase + FSPI_LUTKEY);
@@ -827,6 +832,31 @@  static int nxp_fspi_adjust_op_size(struct spi_slave *slave,
 	return 0;
 }
 
+static void erratum_err050568(struct nxp_fspi *f)
+{
+	struct sys_info sysinfo;
+	u32 svr = 0, freq = 0;
+
+	/* Check for LS1028A variants */
+	svr = SVR_SOC_VER(get_svr());
+	if (svr != SVR_LS1017A ||
+	    svr != SVR_LS1018A ||
+	    svr != SVR_LS1027A ||
+	    svr != SVR_LS1028A) {
+		dev_dbg(f->dev, "Errata applicable only for LS1028A variants\n");
+		return;
+	}
+
+	/* Read PLL frequency */
+	get_sys_info(&sysinfo);
+	freq = sysinfo.freq_systembus / 1000000; /* Convert to MHz */
+	dev_dbg(f->dev, "svr: %08x, Frequency: %dMhz\n", svr, freq);
+
+	/* Use IP bus only if PLL is 300MHz */
+	if (freq == 300)
+		f->devtype_data->quirks |= FSPI_QUIRK_USE_IP_ONLY;
+}
+
 static int nxp_fspi_default_setup(struct nxp_fspi *f)
 {
 	void __iomem *base = f->iobase;
@@ -847,6 +877,15 @@  static int nxp_fspi_default_setup(struct nxp_fspi *f)
 		return ret;
 #endif
 
+	/*
+	 * ERR050568: Flash access by FlexSPI AHB command may not work with
+	 * platform frequency equal to 300 MHz on LS1028A.
+	 * LS1028A reuses LX2160A compatible entry. Make errata applicable for
+	 * Layerscape LS1028A platform family.
+	 */
+	if (device_is_compatible(f->dev, "nxp,lx2160a-fspi"))
+		erratum_err050568(f);
+
 	/* Reset the module */
 	/* w1c register, wait unit clear */
 	ret = fspi_readl_poll_tout(f, f->iobase + FSPI_MCR0,