From d2d88e3432d68b11b0add84bd15a3aadaf44f1c1 Mon Sep 17 00:00:00 2001
From: Yunhui Cui <B56489@freescale.com>
Date: Mon, 28 Dec 2015 18:25:56 +0800
Subject: [PATCH 102/113] mtd: spi-nor: fsl-quadspi:Support qspi for ls2080a

There is a hardware feature that qspi_amba_base is added
internally by SOC design on ls2080a. So as to software, the driver
need support to the feature.

Signed-off-by: Yunhui Cui <B56489@freescale.com>
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c |   24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -41,6 +41,8 @@
 #define QUADSPI_QUIRK_TKT253890		(1 << 2)
 /* Controller cannot wake up from wait mode, TKT245618 */
 #define QUADSPI_QUIRK_TKT245618         (1 << 3)
+/* QSPI_AMBA_BASE is internally added by SOC design */
+#define QUADSPI_AMBA_BASE_INTERNAL	(0x10000)
 
 /* The registers */
 #define QUADSPI_MCR			0x00
@@ -217,6 +219,7 @@ enum fsl_qspi_devtype {
 	FSL_QUADSPI_IMX7D,
 	FSL_QUADSPI_IMX6UL,
 	FSL_QUADSPI_LS1021A,
+	FSL_QUADSPI_LS2080A,
 };
 
 struct fsl_qspi_devtype_data {
@@ -270,6 +273,14 @@ static struct fsl_qspi_devtype_data ls10
 	.driver_data = 0,
 };
 
+static struct fsl_qspi_devtype_data ls2080a_data = {
+	.devtype = FSL_QUADSPI_LS2080A,
+	.rxfifo = 128,
+	.txfifo = 64,
+	.ahb_buf_size = 1024,
+	.driver_data = QUADSPI_AMBA_BASE_INTERNAL,
+};
+
 #define FSL_QSPI_MAX_CHIP	4
 struct fsl_qspi {
 	struct spi_nor nor[FSL_QSPI_MAX_CHIP];
@@ -312,6 +323,11 @@ static inline int needs_wakeup_wait_mode
 	return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT245618;
 }
 
+static inline int has_added_amba_base_internal(struct fsl_qspi *q)
+{
+	return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
+}
+
 /*
  * R/W functions for big- or little-endian registers:
  * The qSPI controller's endian is independent of the CPU core's endian.
@@ -558,8 +574,11 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
 	/* save the reg */
 	reg = qspi_readl(q, base + QUADSPI_MCR);
 
-	qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
-			base + QUADSPI_SFAR);
+	if (has_added_amba_base_internal(q))
+		qspi_writel(q, q->chip_base_addr + addr, base + QUADSPI_SFAR);
+	else
+		qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
+			    base + QUADSPI_SFAR);
 	qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
 			base + QUADSPI_RBCT);
 	qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
@@ -849,6 +868,7 @@ static const struct of_device_id fsl_qsp
 	{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
 	{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
 	{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
+	{ .compatible = "fsl,ls2080a-qspi", .data = (void *)&ls2080a_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
