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

Frank Li
2024-09-05T15:03:09Z

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
>