From 7fa0b7d9767732b73f85b53952913256922c817b Mon Sep 17 00:00:00 2001 From: Han Xu Date: Thu, 8 Oct 2020 11:25:09 -0500 Subject: MLK-24870-1: spi: spi-nxp-fspi: Use IPS to read data on iMX8DXL Latest SCFW disabled to access nor memory via AHB due to the DXL IC errata, added dedicate compatible string for DXL and changed the driver for DXL to use IPS to read data. Signed-off-by: Han Xu Reviewed-by: Frank Li --- drivers/spi/spi-nxp-fspi.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c index db9302ea92db..7dc8afed6713 100644 --- a/drivers/spi/spi-nxp-fspi.c +++ b/drivers/spi/spi-nxp-fspi.c @@ -314,6 +314,9 @@ #define NXP_FSPI_MAX_CHIPSELECT 4 #define NXP_FSPI_MIN_IOMAP SZ_4M +/* access memory via IPS only due to this errata */ +#define NXP_FSPI_QUIRK_ERR050601 BIT(0) + struct nxp_fspi_devtype_data { unsigned int rxfifo; unsigned int txfifo; @@ -346,6 +349,14 @@ static const struct nxp_fspi_devtype_data imx8qxp_data = { .little_endian = true, /* little-endian */ }; +static const struct nxp_fspi_devtype_data imx8dxl_data = { + .rxfifo = SZ_512, /* (64 * 64 bits) */ + .txfifo = SZ_1K, /* (128 * 64 bits) */ + .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ + .quirks = NXP_FSPI_QUIRK_ERR050601, + .little_endian = true, /* little-endian */ +}; + struct nxp_fspi { void __iomem *iobase; void __iomem *ahb_addr; @@ -364,6 +375,11 @@ struct nxp_fspi { int flags; }; +static inline int nxp_fspi_ips_access_only(struct nxp_fspi *f) +{ + return f->devtype_data->quirks & NXP_FSPI_QUIRK_ERR050601; +} + /* * R/W functions for big- or little-endian registers: * The FSPI controller's endianness is independent of @@ -857,9 +873,11 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) /* * If we have large chunks of data, we read them through the AHB bus * by accessing the mapped memory. In all other cases we use - * IP commands to access the flash. + * IP commands to access the flash, but ahb read won't be used for dxl + * since IC errta. */ - if (op->data.nbytes > (f->devtype_data->rxfifo - 4) && + if (!nxp_fspi_ips_access_only(f) && + op->data.nbytes > (f->devtype_data->rxfifo - 4) && op->data.dir == SPI_MEM_DATA_IN) { err = nxp_fspi_read_ahb(f, op); } else { @@ -894,6 +912,10 @@ static int nxp_fspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) op->data.nbytes = f->devtype_data->ahb_buf_size; else if (op->data.nbytes > (f->devtype_data->rxfifo - 4)) op->data.nbytes = ALIGN_DOWN(op->data.nbytes, 8); + /* dxl won't use ahb to access data, limit to rxfifo size */ + if (nxp_fspi_ips_access_only(f) && + op->data.nbytes > f->devtype_data->rxfifo) + op->data.nbytes = f->devtype_data->rxfifo; } return 0; @@ -1182,6 +1204,7 @@ static const struct of_device_id nxp_fspi_dt_ids[] = { { .compatible = "nxp,lx2160a-fspi", .data = (void *)&lx2160a_data, }, { .compatible = "nxp,imx8mm-fspi", .data = (void *)&imx8mm_data, }, { .compatible = "nxp,imx8qxp-fspi", .data = (void *)&imx8qxp_data, }, + { .compatible = "nxp,imx8dxl-fspi", .data = (void *)&imx8dxl_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids); -- cgit v1.2.3