diff mbox series

[v3,2/4] spi: fspi: involve lut_num for struct nxp_fspi_devtype_data

Message ID 20240905094338.1986871-3-haibo.chen@nxp.com (mailing list archive)
State Accepted
Commit 190b7e2efb1ed8435fc7431d9c7a2447d05d5066
Headers show
Series fix the flexspi error on imx8ulp | expand

Commit Message

Bough Chen Sept. 5, 2024, 9:43 a.m. UTC
From: Haibo Chen <haibo.chen@nxp.com>

The flexspi on different SoCs may have different number of LUTs.
So involve lut_num in nxp_fspi_devtype_data to make distinguish.
This patch prepare for the adding of imx8ulp.

Fixes: ef89fd56bdfc ("arm64: dts: imx8ulp: add flexspi node")
Cc: stable@kernel.org
Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
---
 drivers/spi/spi-nxp-fspi.c | 44 ++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 19 deletions(-)

Comments

Frank Li Sept. 5, 2024, 3:01 p.m. UTC | #1
On Thu, Sep 05, 2024 at 05:43:36PM +0800, haibo.chen@nxp.com wrote:
> From: Haibo Chen <haibo.chen@nxp.com>
>
> The flexspi on different SoCs may have different number of LUTs.
> So involve lut_num in nxp_fspi_devtype_data to make distinguish.
> This patch prepare for the adding of imx8ulp.
>
> Fixes: ef89fd56bdfc ("arm64: dts: imx8ulp: add flexspi node")
> Cc: stable@kernel.org
> Signed-off-by: Haibo Chen <haibo.chen@nxp.com>

Reviewed-by: Frank Li <Frank.Li@nxp.com>

> ---
>  drivers/spi/spi-nxp-fspi.c | 44 ++++++++++++++++++++++----------------
>  1 file changed, 25 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
> index fd1816befcd8..f42c14d80289 100644
> --- a/drivers/spi/spi-nxp-fspi.c
> +++ b/drivers/spi/spi-nxp-fspi.c
> @@ -57,13 +57,6 @@
>  #include <linux/spi/spi.h>
>  #include <linux/spi/spi-mem.h>
>
> -/*
> - * The driver only uses one single LUT entry, that is updated on
> - * each call of exec_op(). Index 0 is preset at boot with a basic
> - * read operation, so let's use the last entry (31).
> - */
> -#define	SEQID_LUT			31
> -
>  /* Registers used by the driver */
>  #define FSPI_MCR0			0x00
>  #define FSPI_MCR0_AHB_TIMEOUT(x)	((x) << 24)
> @@ -263,9 +256,6 @@
>  #define FSPI_TFDR			0x180
>
>  #define FSPI_LUT_BASE			0x200
> -#define FSPI_LUT_OFFSET			(SEQID_LUT * 4 * 4)
> -#define FSPI_LUT_REG(idx) \
> -	(FSPI_LUT_BASE + FSPI_LUT_OFFSET + (idx) * 4)
>
>  /* register map end */
>
> @@ -341,6 +331,7 @@ struct nxp_fspi_devtype_data {
>  	unsigned int txfifo;
>  	unsigned int ahb_buf_size;
>  	unsigned int quirks;
> +	unsigned int lut_num;
>  	bool little_endian;
>  };
>
> @@ -349,6 +340,7 @@ static struct nxp_fspi_devtype_data lx2160a_data = {
>  	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
>  	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
>  	.quirks = 0,
> +	.lut_num = 32,
>  	.little_endian = true,  /* little-endian    */
>  };
>
> @@ -357,6 +349,7 @@ static struct nxp_fspi_devtype_data imx8mm_data = {
>  	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
>  	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
>  	.quirks = 0,
> +	.lut_num = 32,
>  	.little_endian = true,  /* little-endian    */
>  };
>
> @@ -365,6 +358,7 @@ static struct nxp_fspi_devtype_data imx8qxp_data = {
>  	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
>  	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
>  	.quirks = 0,
> +	.lut_num = 32,
>  	.little_endian = true,  /* little-endian    */
>  };
>
> @@ -373,6 +367,7 @@ static struct nxp_fspi_devtype_data imx8dxl_data = {
>  	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
>  	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
>  	.quirks = FSPI_QUIRK_USE_IP_ONLY,
> +	.lut_num = 32,
>  	.little_endian = true,  /* little-endian    */
>  };
>
> @@ -544,6 +539,8 @@ static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
>  	void __iomem *base = f->iobase;
>  	u32 lutval[4] = {};
>  	int lutidx = 1, i;
> +	u32 lut_offset = (f->devtype_data->lut_num - 1) * 4 * 4;
> +	u32 target_lut_reg;
>
>  	/* cmd */
>  	lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth),
> @@ -588,8 +585,10 @@ static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
>  	fspi_writel(f, FSPI_LCKER_UNLOCK, f->iobase + FSPI_LCKCR);
>
>  	/* fill LUT */
> -	for (i = 0; i < ARRAY_SIZE(lutval); i++)
> -		fspi_writel(f, lutval[i], base + FSPI_LUT_REG(i));
> +	for (i = 0; i < ARRAY_SIZE(lutval); i++) {
> +		target_lut_reg = FSPI_LUT_BASE + lut_offset + i * 4;
> +		fspi_writel(f, lutval[i], base + target_lut_reg);
> +	}
>
>  	dev_dbg(f->dev, "CMD[%02x] lutval[0:%08x 1:%08x 2:%08x 3:%08x], size: 0x%08x\n",
>  		op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3], op->data.nbytes);
> @@ -874,7 +873,7 @@ static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op)
>  	void __iomem *base = f->iobase;
>  	int seqnum = 0;
>  	int err = 0;
> -	u32 reg;
> +	u32 reg, seqid_lut;
>
>  	reg = fspi_readl(f, base + FSPI_IPRXFCR);
>  	/* invalid RXFIFO first */
> @@ -890,8 +889,9 @@ static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op)
>  	 * the LUT at each exec_op() call. And also specify the DATA
>  	 * length, since it's has not been specified in the LUT.
>  	 */
> +	seqid_lut = f->devtype_data->lut_num - 1;
>  	fspi_writel(f, op->data.nbytes |
> -		 (SEQID_LUT << FSPI_IPCR1_SEQID_SHIFT) |
> +		 (seqid_lut << FSPI_IPCR1_SEQID_SHIFT) |
>  		 (seqnum << FSPI_IPCR1_SEQNUM_SHIFT),
>  		 base + FSPI_IPCR1);
>
> @@ -1015,7 +1015,7 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f)
>  {
>  	void __iomem *base = f->iobase;
>  	int ret, i;
> -	u32 reg;
> +	u32 reg, seqid_lut;
>
>  	/* disable and unprepare clock to avoid glitch pass to controller */
>  	nxp_fspi_clk_disable_unprep(f);
> @@ -1090,11 +1090,17 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f)
>  	fspi_writel(f, reg, base + FSPI_FLSHB1CR1);
>  	fspi_writel(f, reg, base + FSPI_FLSHB2CR1);
>
> +	/*
> +	 * The driver only uses one single LUT entry, that is updated on
> +	 * each call of exec_op(). Index 0 is preset at boot with a basic
> +	 * read operation, so let's use the last entry.
> +	 */
> +	seqid_lut = f->devtype_data->lut_num - 1;
>  	/* AHB Read - Set lut sequence ID for all CS. */
> -	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2);
> -	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2);
> -	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHB1CR2);
> -	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHB2CR2);
> +	fspi_writel(f, seqid_lut, base + FSPI_FLSHA1CR2);
> +	fspi_writel(f, seqid_lut, base + FSPI_FLSHA2CR2);
> +	fspi_writel(f, seqid_lut, base + FSPI_FLSHB1CR2);
> +	fspi_writel(f, seqid_lut, base + FSPI_FLSHB2CR2);
>
>  	f->selected = -1;
>
> --
> 2.34.1
>
diff mbox series

Patch

diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index fd1816befcd8..f42c14d80289 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -57,13 +57,6 @@ 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi-mem.h>
 
-/*
- * The driver only uses one single LUT entry, that is updated on
- * each call of exec_op(). Index 0 is preset at boot with a basic
- * read operation, so let's use the last entry (31).
- */
-#define	SEQID_LUT			31
-
 /* Registers used by the driver */
 #define FSPI_MCR0			0x00
 #define FSPI_MCR0_AHB_TIMEOUT(x)	((x) << 24)
@@ -263,9 +256,6 @@ 
 #define FSPI_TFDR			0x180
 
 #define FSPI_LUT_BASE			0x200
-#define FSPI_LUT_OFFSET			(SEQID_LUT * 4 * 4)
-#define FSPI_LUT_REG(idx) \
-	(FSPI_LUT_BASE + FSPI_LUT_OFFSET + (idx) * 4)
 
 /* register map end */
 
@@ -341,6 +331,7 @@  struct nxp_fspi_devtype_data {
 	unsigned int txfifo;
 	unsigned int ahb_buf_size;
 	unsigned int quirks;
+	unsigned int lut_num;
 	bool little_endian;
 };
 
@@ -349,6 +340,7 @@  static struct nxp_fspi_devtype_data lx2160a_data = {
 	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
 	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
 	.quirks = 0,
+	.lut_num = 32,
 	.little_endian = true,  /* little-endian    */
 };
 
@@ -357,6 +349,7 @@  static struct nxp_fspi_devtype_data imx8mm_data = {
 	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
 	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
 	.quirks = 0,
+	.lut_num = 32,
 	.little_endian = true,  /* little-endian    */
 };
 
@@ -365,6 +358,7 @@  static struct nxp_fspi_devtype_data imx8qxp_data = {
 	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
 	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
 	.quirks = 0,
+	.lut_num = 32,
 	.little_endian = true,  /* little-endian    */
 };
 
@@ -373,6 +367,7 @@  static struct nxp_fspi_devtype_data imx8dxl_data = {
 	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
 	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
 	.quirks = FSPI_QUIRK_USE_IP_ONLY,
+	.lut_num = 32,
 	.little_endian = true,  /* little-endian    */
 };
 
@@ -544,6 +539,8 @@  static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
 	void __iomem *base = f->iobase;
 	u32 lutval[4] = {};
 	int lutidx = 1, i;
+	u32 lut_offset = (f->devtype_data->lut_num - 1) * 4 * 4;
+	u32 target_lut_reg;
 
 	/* cmd */
 	lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth),
@@ -588,8 +585,10 @@  static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
 	fspi_writel(f, FSPI_LCKER_UNLOCK, f->iobase + FSPI_LCKCR);
 
 	/* fill LUT */
-	for (i = 0; i < ARRAY_SIZE(lutval); i++)
-		fspi_writel(f, lutval[i], base + FSPI_LUT_REG(i));
+	for (i = 0; i < ARRAY_SIZE(lutval); i++) {
+		target_lut_reg = FSPI_LUT_BASE + lut_offset + i * 4;
+		fspi_writel(f, lutval[i], base + target_lut_reg);
+	}
 
 	dev_dbg(f->dev, "CMD[%02x] lutval[0:%08x 1:%08x 2:%08x 3:%08x], size: 0x%08x\n",
 		op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3], op->data.nbytes);
@@ -874,7 +873,7 @@  static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op)
 	void __iomem *base = f->iobase;
 	int seqnum = 0;
 	int err = 0;
-	u32 reg;
+	u32 reg, seqid_lut;
 
 	reg = fspi_readl(f, base + FSPI_IPRXFCR);
 	/* invalid RXFIFO first */
@@ -890,8 +889,9 @@  static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op)
 	 * the LUT at each exec_op() call. And also specify the DATA
 	 * length, since it's has not been specified in the LUT.
 	 */
+	seqid_lut = f->devtype_data->lut_num - 1;
 	fspi_writel(f, op->data.nbytes |
-		 (SEQID_LUT << FSPI_IPCR1_SEQID_SHIFT) |
+		 (seqid_lut << FSPI_IPCR1_SEQID_SHIFT) |
 		 (seqnum << FSPI_IPCR1_SEQNUM_SHIFT),
 		 base + FSPI_IPCR1);
 
@@ -1015,7 +1015,7 @@  static int nxp_fspi_default_setup(struct nxp_fspi *f)
 {
 	void __iomem *base = f->iobase;
 	int ret, i;
-	u32 reg;
+	u32 reg, seqid_lut;
 
 	/* disable and unprepare clock to avoid glitch pass to controller */
 	nxp_fspi_clk_disable_unprep(f);
@@ -1090,11 +1090,17 @@  static int nxp_fspi_default_setup(struct nxp_fspi *f)
 	fspi_writel(f, reg, base + FSPI_FLSHB1CR1);
 	fspi_writel(f, reg, base + FSPI_FLSHB2CR1);
 
+	/*
+	 * The driver only uses one single LUT entry, that is updated on
+	 * each call of exec_op(). Index 0 is preset at boot with a basic
+	 * read operation, so let's use the last entry.
+	 */
+	seqid_lut = f->devtype_data->lut_num - 1;
 	/* AHB Read - Set lut sequence ID for all CS. */
-	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2);
-	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2);
-	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHB1CR2);
-	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHB2CR2);
+	fspi_writel(f, seqid_lut, base + FSPI_FLSHA1CR2);
+	fspi_writel(f, seqid_lut, base + FSPI_FLSHA2CR2);
+	fspi_writel(f, seqid_lut, base + FSPI_FLSHB1CR2);
+	fspi_writel(f, seqid_lut, base + FSPI_FLSHB2CR2);
 
 	f->selected = -1;