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

Kuldeep Singh kuldeep.singh at nxp.com
Mon Mar 22 07:35:31 CET 2021


+ Ye Li

> -----Original Message-----
> From: Kuldeep Singh <kuldeep.singh at nxp.com>
> Sent: Monday, March 22, 2021 12:00 PM
> To: Jagan Teki <jagan at amarulasolutions.com>; u-boot at lists.denx.de
> Cc: Kuldeep Singh <kuldeep.singh at 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 at 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



More information about the U-Boot mailing list