diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 5941520..dc8a958 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -149,6 +149,14 @@ config FSL_QSPI
 	  used to access the SPI NOR flash on platforms embedding this
 	  Freescale IP core.
 
+config FSL_QSPI_AHB_FULL_MAP
+	bool "Use full AHB memory map space"
+	depends on FSL_QSPI
+	default y if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP || ARCH_IMX8M
+	help
+	  Enable the Freescale QSPI driver to use full AHB memory map space for
+	  flash access.
+
 config ICH_SPI
 	bool "Intel ICH SPI driver"
 	help
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index d9f531a..eec968e 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -46,6 +46,7 @@ DECLARE_GLOBAL_DATA_PTR;
  * read operation, so let's use the last entry (15).
  */
 #define	SEQID_LUT			15
+#define	SEQID_LUT_AHB		14
 
 /* Registers used by the driver */
 #define QUADSPI_MCR			0x00
@@ -122,6 +123,10 @@ DECLARE_GLOBAL_DATA_PTR;
 #define QUADSPI_LUT_REG(idx) \
 	(QUADSPI_LUT_BASE + QUADSPI_LUT_OFFSET + (idx) * 4)
 
+#define QUADSPI_AHB_LUT_OFFSET		(SEQID_LUT_AHB * 4 * 4)
+#define QUADSPI_AHB_LUT_REG(idx) \
+	(QUADSPI_LUT_BASE + QUADSPI_AHB_LUT_OFFSET + (idx) * 4)
+
 /* Instruction set for the LUT register */
 #define LUT_STOP		0
 #define LUT_CMD			1
@@ -189,6 +194,11 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 #define QUADSPI_QUIRK_USE_TDH_SETTING	BIT(5)
 
+/*
+ * Controller only has Two CS on flash A, no flash B port
+ */
+#define QUADSPI_QUIRK_SINGLE_BUS		BIT(6)
+
 struct fsl_qspi_devtype_data {
 	unsigned int rxfifo;
 	unsigned int txfifo;
@@ -236,7 +246,7 @@ static const struct fsl_qspi_devtype_data imx7ulp_data = {
 	.txfifo = SZ_64,
 	.ahb_buf_size = SZ_128,
 	.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
-		  QUADSPI_QUIRK_USE_TDH_SETTING,
+		  QUADSPI_QUIRK_USE_TDH_SETTING | QUADSPI_QUIRK_SINGLE_BUS,
 	.little_endian = true,
 };
 
@@ -269,6 +279,7 @@ struct fsl_qspi {
 	void __iomem *iobase;
 	void __iomem *ahb_addr;
 	u32 memmap_phy;
+	u32 memmap_size;
 	const struct fsl_qspi_devtype_data *devtype_data;
 	int selected;
 };
@@ -303,6 +314,11 @@ static inline int needs_tdh_setting(struct fsl_qspi *q)
 	return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING;
 }
 
+static inline int needs_single_bus(struct fsl_qspi *q)
+{
+	return q->devtype_data->quirks & QUADSPI_QUIRK_SINGLE_BUS;
+}
+
 /*
  * An IC bug makes it necessary to rearrange the 32-bit data.
  * Later chips, such as IMX6SLX, have fixed this bug.
@@ -405,18 +421,27 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q,
 	lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth),
 			     op->cmd.opcode);
 
-	/*
-	 * For some unknown reason, using LUT_ADDR doesn't work in some
-	 * cases (at least with only one byte long addresses), so
-	 * let's use LUT_MODE to write the address bytes one by one
-	 */
-	for (i = 0; i < op->addr.nbytes; i++) {
-		u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1));
-
-		lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE,
-					      LUT_PAD(op->addr.buswidth),
-					      addrbyte);
-		lutidx++;
+	if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
+		if (op->addr.nbytes) {
+			lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_ADDR,
+						      LUT_PAD(op->addr.buswidth),
+						      (op->addr.nbytes == 4) ? 0x20 : 0x18);
+			lutidx++;
+		}
+	} else {
+		/*
+		 * For some unknown reason, using LUT_ADDR doesn't work in some
+		 * cases (at least with only one byte long addresses), so
+		 * let's use LUT_MODE to write the address bytes one by one
+		 */
+		for (i = 0; i < op->addr.nbytes; i++) {
+			u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1));
+
+			lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE,
+						      LUT_PAD(op->addr.buswidth),
+						      addrbyte);
+			lutidx++;
+		}
 	}
 
 	if (op->dummy.nbytes) {
@@ -449,6 +474,14 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q,
 	for (i = 0; i < ARRAY_SIZE(lutval); i++)
 		qspi_writel(q, lutval[i], base + QUADSPI_LUT_REG(i));
 
+	if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
+		if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN &&
+		    op->addr.nbytes) {
+			for (i = 0; i < ARRAY_SIZE(lutval); i++)
+				qspi_writel(q, lutval[i], base + QUADSPI_AHB_LUT_REG(i));
+		}
+	}
+
 	/* lock LUT */
 	qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
 	qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
@@ -491,10 +524,29 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_slave *slave)
 	fsl_qspi_invalidate(q);
 }
 
+static u32 fsl_qspi_memsize_per_cs(struct fsl_qspi *q)
+{
+	if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
+		if (needs_single_bus(q))
+			return q->memmap_size / 2;
+		else
+			return q->memmap_size / 4;
+	} else {
+		return ALIGN(q->devtype_data->ahb_buf_size, 0x400);
+	}
+}
+
 static void fsl_qspi_read_ahb(struct fsl_qspi *q, const struct spi_mem_op *op)
 {
+	void __iomem *ahb_read_addr = q->ahb_addr;
+
+	if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
+		if (op->addr.nbytes)
+			ahb_read_addr += op->addr.val;
+	}
+
 	memcpy_fromio(op->data.buf.in,
-		      q->ahb_addr + q->selected * ALIGN(q->devtype_data->ahb_buf_size, 0x400),
+		      ahb_read_addr + q->selected * fsl_qspi_memsize_per_cs(q),
 		      op->data.nbytes);
 }
 
@@ -597,8 +649,13 @@ static int fsl_qspi_exec_op(struct spi_slave *slave,
 	if (needs_amba_base_offset(q))
 		addr_offset = q->memmap_phy;
 
+	if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
+		if (op->addr.nbytes)
+			addr_offset += op->addr.val;
+	}
+
 	qspi_writel(q,
-		    q->selected * ALIGN(q->devtype_data->ahb_buf_size, 0x400) + addr_offset,
+		    q->selected * fsl_qspi_memsize_per_cs(q) + addr_offset,
 		    base + QUADSPI_SFAR);
 
 	qspi_writel(q, qspi_readl(q, base + QUADSPI_MCR) |
@@ -655,7 +712,7 @@ static int fsl_qspi_adjust_op_size(struct spi_slave *slave,
 static int fsl_qspi_default_setup(struct fsl_qspi *q)
 {
 	void __iomem *base = q->iobase;
-	u32 reg, addr_offset = 0;
+	u32 reg, addr_offset = 0, memsize_cs;
 
 	/* Reset the module */
 	qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
@@ -687,8 +744,13 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q)
 	qspi_writel(q, 0, base + QUADSPI_BUF1IND);
 	qspi_writel(q, 0, base + QUADSPI_BUF2IND);
 
-	qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT),
-		    q->iobase + QUADSPI_BFGENCR);
+	if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP))
+		qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT_AHB),
+			    q->iobase + QUADSPI_BFGENCR);
+	else
+		qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT),
+			    q->iobase + QUADSPI_BFGENCR);
+
 	qspi_writel(q, QUADSPI_RBCT_WMRK_MASK, base + QUADSPI_RBCT);
 	qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
 		    QUADSPI_BUF3CR_ADATSZ(q->devtype_data->ahb_buf_size / 8),
@@ -704,14 +766,17 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q)
 	 * We use ahb_buf_size for each chip and set SFA1AD, SFA2AD, SFB1AD,
 	 * SFB2AD accordingly.
 	 */
-	qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) + addr_offset,
+	memsize_cs = fsl_qspi_memsize_per_cs(q);
+	qspi_writel(q, memsize_cs + addr_offset,
 		    base + QUADSPI_SFA1AD);
-	qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 2 + addr_offset,
+	qspi_writel(q, memsize_cs * 2 + addr_offset,
 		    base + QUADSPI_SFA2AD);
-	qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 3 + addr_offset,
-		    base + QUADSPI_SFB1AD);
-	qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 4 + addr_offset,
-		    base + QUADSPI_SFB2AD);
+	if (!needs_single_bus(q)) {
+		qspi_writel(q, memsize_cs * 3 + addr_offset,
+			    base + QUADSPI_SFB1AD);
+		qspi_writel(q, memsize_cs * 4 + addr_offset,
+			    base + QUADSPI_SFB2AD);
+	}
 
 	q->selected = -1;
 
@@ -759,6 +824,7 @@ static int fsl_qspi_probe(struct udevice *bus)
 
 	q->ahb_addr = map_physmem(res.start, res.end - res.start, MAP_NOCACHE);
 	q->memmap_phy = res.start;
+	q->memmap_size = res.end - res.start;
 
 	dm_bus->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
 					66000000);
