summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHan Xu <han.xu@nxp.com>2020-10-08 11:25:09 -0500
committerHan Xu <han.xu@nxp.com>2020-10-08 13:57:53 -0500
commit7fa0b7d9767732b73f85b53952913256922c817b (patch)
tree27313af227c4bbd66a5dc292470b1acf3a045587
parent2f68e5475b11c03ea9148857ad0094c306a859af (diff)
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 <han.xu@nxp.com> Reviewed-by: Frank Li <frank.li@nxp.com>
-rw-r--r--drivers/spi/spi-nxp-fspi.c27
1 files 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);