-From 120fa458ffe2250ea58578ccfc85e674005463dc Mon Sep 17 00:00:00 2001
+From a3757157751a8a5302ee5e11faf828dc5db02018 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Mon, 25 Sep 2017 10:53:50 +0800
Subject: [PATCH] mtd: spi-nor: support layerscape
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/mtd/mtdchar.c | 2 +-
- drivers/mtd/spi-nor/fsl-quadspi.c | 356 +++++++++++++++++++++++++++++++-------
- drivers/mtd/spi-nor/spi-nor.c | 136 +++++++++++++--
+ drivers/mtd/spi-nor/fsl-quadspi.c | 327 +++++++++++++++++++++++++++++++-------
+ drivers/mtd/spi-nor/spi-nor.c | 136 ++++++++++++++--
include/linux/mtd/spi-nor.h | 14 +-
- 4 files changed, 432 insertions(+), 76 deletions(-)
+ 4 files changed, 409 insertions(+), 70 deletions(-)
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 2a47a3f0..4f21401d 100644
*
* Note: currently the standard NAND function, nand_read_oob_std,
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
-index 5c82e4ef..8fb75532 100644
+index 5c82e4ef..33ecc27a 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -41,6 +41,8 @@
}
/*
-@@ -681,19 +860,36 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
- {
- void __iomem *base = q->iobase;
- int seqid;
-+ const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
-
- /* AHB configuration for access buffer 0/1/2 .*/
- qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
- qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
- qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
-+
- /*
-- * Set ADATSZ with the maximum AHB buffer size to improve the
-- * read performance.
-+ * Errata: A-009282: QuadSPI data prefetch may result in incorrect data
-+ * Workaround: Keep the read data size to 64 bits (8 bytes).
-+ * This disables the prefetch on the AHB buffer and
-+ * prevents this issue from occurring.
- */
-- qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
-- ((q->devtype_data->ahb_buf_size / 8)
-- << QUADSPI_BUF3CR_ADATSZ_SHIFT),
-- base + QUADSPI_BUF3CR);
-+ if (devtype_data->devtype == FSL_QUADSPI_LS2080A ||
-+ devtype_data->devtype == FSL_QUADSPI_LS1021A) {
-+
-+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
-+ (1 << QUADSPI_BUF3CR_ADATSZ_SHIFT),
-+ base + QUADSPI_BUF3CR);
-+
-+ } else {
-+ /*
-+ * Set ADATSZ with the maximum AHB buffer size to improve the
-+ * read performance.
-+ */
-+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
-+ ((q->devtype_data->ahb_buf_size / 8)
-+ << QUADSPI_BUF3CR_ADATSZ_SHIFT),
-+ base + QUADSPI_BUF3CR);
-+ }
-
- /* We only use the buffer3 */
- qspi_writel(q, 0, base + QUADSPI_BUF0IND);
-@@ -704,6 +900,11 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
+@@ -704,6 +883,11 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
q->iobase + QUADSPI_BFGENCR);
}
/* This function was used to prepare and enable QSPI clock */
-@@ -822,6 +1023,7 @@ static const struct of_device_id fsl_qspi_dt_ids[] = {
+@@ -822,6 +1006,7 @@ static const struct of_device_id fsl_qspi_dt_ids[] = {
{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
-@@ -835,8 +1037,12 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
+@@ -835,8 +1020,12 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
{
int ret;
struct fsl_qspi *q = nor->priv;
+ u32 to = 0;
-+
-+ if (opcode == SPINOR_OP_SPANSION_RDAR)
-+ u8tou32(&to, nor->cmd_buf, 4);
- ret = fsl_qspi_runcmd(q, opcode, 0, len);
++ if (opcode == SPINOR_OP_SPANSION_RDAR)
++ u8tou32(&to, nor->cmd_buf, 4);
++
+ ret = fsl_qspi_runcmd(q, opcode, to, len);
if (ret)
return ret;
-@@ -848,9 +1054,13 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
+@@ -848,9 +1037,13 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
{
struct fsl_qspi *q = nor->priv;
int ret;
if (ret)
return ret;
-@@ -859,7 +1069,7 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
+@@ -859,7 +1052,7 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
} else if (len > 0) {
ret = fsl_qspi_nor_write(q, nor, opcode, 0,
if (ret > 0)
return 0;
} else {
-@@ -875,7 +1085,7 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
+@@ -875,7 +1068,7 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
{
struct fsl_qspi *q = nor->priv;
ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
/* invalid the data in the AHB buffer. */
fsl_qspi_invalid(q);
-@@ -922,7 +1132,7 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
+@@ -922,7 +1115,7 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
len);
/* Read out the data directly from the AHB buffer.*/
len);
return len;
-@@ -980,6 +1190,8 @@ static int fsl_qspi_probe(struct platform_device *pdev)
+@@ -980,6 +1173,8 @@ static int fsl_qspi_probe(struct platform_device *pdev)
struct spi_nor *nor;
struct mtd_info *mtd;
int ret, i = 0;
q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
if (!q)
-@@ -1027,6 +1239,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
+@@ -1027,6 +1222,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
goto clk_failed;
}
/* find the irq */
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
-@@ -1050,6 +1268,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
+@@ -1050,6 +1251,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
mutex_init(&q->lock);
/* iterate the subnodes. */
for_each_available_child_of_node(dev->of_node, np) {
/* skip the holes */
-@@ -1076,18 +1295,25 @@ static int fsl_qspi_probe(struct platform_device *pdev)
+@@ -1076,18 +1278,25 @@ static int fsl_qspi_probe(struct platform_device *pdev)
ret = of_property_read_u32(np, "spi-max-frequency",
&q->clk_rate);
if (ret < 0)
/* Set the correct NOR size now. */
if (q->nor_size == 0) {
-@@ -1110,8 +1336,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
+@@ -1110,8 +1319,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
nor->page_size = q->devtype_data->txfifo;
i++;