diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index ad4f4ced17b56a2709284c414ac6292a5eb99abd..5e0b0692747cb7791c38e33783c515629f8ba6ff 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -263,6 +263,110 @@ static void qspi_set_lut(struct fsl_qspi *qspi)
 	qspi_write32(&regs->lckcr, QSPI_LCKCR_LOCK);
 }
 
+#if defined(CONFIG_SYS_FSL_QSPI_AHB)
+/*
+ * If we have changed the content of the flash by writing or erasing,
+ * we need to invalidate the AHB buffer. If we do not do so, we may read out
+ * the wrong data. The spec tells us reset the AHB domain and Serial Flash
+ * domain at the same time.
+ */
+static inline void qspi_ahb_invalid(struct fsl_qspi *q)
+{
+	struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)q->reg_base;
+	u32 reg;
+
+	reg = qspi_read32(&regs->mcr);
+	reg |= QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK;
+	qspi_write32(&regs->mcr, reg);
+
+	/*
+	 * The minimum delay : 1 AHB + 2 SFCK clocks.
+	 * Delay 1 us is enough.
+	 */
+	udelay(1);
+
+	reg &= ~(QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK);
+	qspi_write32(&regs->mcr, reg);
+}
+
+/* Read out the data from the AHB buffer. */
+static inline void qspi_ahb_read(struct fsl_qspi *q, u8 *rxbuf, int len)
+{
+	struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)q->reg_base;
+	u32 mcr_reg;
+
+	mcr_reg = qspi_read32(&regs->mcr);
+
+	qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
+		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
+
+	/* Read out the data directly from the AHB buffer. */
+	memcpy(rxbuf, (u8 *)(q->amba_base + q->sf_addr), len);
+
+	qspi_write32(&regs->mcr, mcr_reg);
+}
+
+static void qspi_enable_ddr_mode(struct fsl_qspi_regs *regs)
+{
+	u32 reg, reg2;
+
+	reg = qspi_read32(&regs->mcr);
+	/* Disable the module */
+	qspi_write32(&regs->mcr, reg | QSPI_MCR_MDIS_MASK);
+
+	/* Set the Sampling Register for DDR */
+	reg2 = qspi_read32(&regs->smpr);
+	reg2 &= ~QSPI_SMPR_DDRSMP_MASK;
+	reg2 |= (2 << QSPI_SMPR_DDRSMP_SHIFT);
+	qspi_write32(&regs->smpr, reg2);
+
+	/* Enable the module again (enable the DDR too) */
+	reg |= QSPI_MCR_DDR_EN_MASK;
+	/* Enable bit 29 for imx6sx */
+	reg |= (1 << 29);
+
+	qspi_write32(&regs->mcr, reg);
+}
+
+/*
+ * There are two different ways to read out the data from the flash:
+ *  the "IP Command Read" and the "AHB Command Read".
+ *
+ * The IC guy suggests we use the "AHB Command Read" which is faster
+ * then the "IP Command Read". (What's more is that there is a bug in
+ * the "IP Command Read" in the Vybrid.)
+ *
+ * After we set up the registers for the "AHB Command Read", we can use
+ * the memcpy to read the data directly. A "missed" access to the buffer
+ * causes the controller to clear the buffer, and use the sequence pointed
+ * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
+ */
+static void qspi_init_ahb_read(struct fsl_qspi_regs *regs)
+{
+	/* AHB configuration for access buffer 0/1/2 .*/
+	qspi_write32(&regs->buf0cr, QSPI_BUFXCR_INVALID_MSTRID);
+	qspi_write32(&regs->buf1cr, QSPI_BUFXCR_INVALID_MSTRID);
+	qspi_write32(&regs->buf2cr, QSPI_BUFXCR_INVALID_MSTRID);
+	qspi_write32(&regs->buf3cr, QSPI_BUF3CR_ALLMST_MASK |
+		     (0x80 << QSPI_BUF3CR_ADATSZ_SHIFT));
+
+	/* We only use the buffer3 */
+	qspi_write32(&regs->buf0ind, 0);
+	qspi_write32(&regs->buf1ind, 0);
+	qspi_write32(&regs->buf2ind, 0);
+
+	/*
+	 * Set the default lut sequence for AHB Read.
+	 * Parallel mode is disabled.
+	 */
+	qspi_write32(&regs->bfgencr,
+		     SEQID_FAST_READ << QSPI_BFGENCR_SEQID_SHIFT);
+
+	/*Enable DDR Mode*/
+	qspi_enable_ddr_mode(regs);
+}
+#endif
+
 void spi_init()
 {
 	/* do nothing */
@@ -273,8 +377,8 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 {
 	struct fsl_qspi *qspi;
 	struct fsl_qspi_regs *regs;
-	u32 reg_val, smpr_val;
-	u32 total_size, seq_id;
+	u32 smpr_val;
+	u32 total_size;
 
 	if (bus >= ARRAY_SIZE(spi_bases))
 		return NULL;
@@ -329,13 +433,9 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 	qspi_write32(&regs->smpr, smpr_val);
 	qspi_write32(&regs->mcr, QSPI_MCR_RESERVED_MASK);
 
-	seq_id = 0;
-	reg_val = qspi_read32(&regs->bfgencr);
-	reg_val &= ~QSPI_BFGENCR_SEQID_MASK;
-	reg_val |= (seq_id << QSPI_BFGENCR_SEQID_SHIFT);
-	reg_val &= ~QSPI_BFGENCR_PAR_EN_MASK;
-	qspi_write32(&regs->bfgencr, reg_val);
-
+#ifdef CONFIG_SYS_FSL_QSPI_AHB
+	qspi_init_ahb_read(regs);
+#endif
 	return &qspi->slave;
 }
 
@@ -426,6 +526,8 @@ static void qspi_op_rdid(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
 	qspi_write32(&regs->mcr, mcr_reg);
 }
 
+#ifndef CONFIG_SYS_FSL_QSPI_AHB
+/* If not use AHB read, read data from ip interface */
 static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
 {
 	struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
@@ -469,6 +571,7 @@ static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
 
 	qspi_write32(&regs->mcr, mcr_reg);
 }
+#endif
 
 static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len)
 {
@@ -643,8 +746,13 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 	}
 
 	if (din) {
-		if (qspi->cur_seqid == QSPI_CMD_FAST_READ)
+		if (qspi->cur_seqid == QSPI_CMD_FAST_READ) {
+#ifdef CONFIG_SYS_FSL_QSPI_AHB
+			qspi_ahb_read(qspi, din, bytes);
+#else
 			qspi_op_read(qspi, din, bytes);
+#endif
+		}
 		else if (qspi->cur_seqid == QSPI_CMD_RDID)
 			qspi_op_rdid(qspi, din, bytes);
 		else if (qspi->cur_seqid == QSPI_CMD_RDSR)
@@ -658,6 +766,15 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 #endif
 	}
 
+#ifdef CONFIG_SYS_FSL_QSPI_AHB
+	if ((qspi->cur_seqid == QSPI_CMD_SE) ||
+	    (qspi->cur_seqid == QSPI_CMD_PP) ||
+	    (qspi->cur_seqid == QSPI_CMD_BE_4K) ||
+	    (qspi->cur_seqid == QSPI_CMD_WREAR) ||
+	    (qspi->cur_seqid == QSPI_CMD_BRWR))
+		qspi_ahb_invalid(qspi);
+#endif
+
 	return 0;
 }
 
diff --git a/drivers/spi/fsl_qspi.h b/drivers/spi/fsl_qspi.h
index db400e66b50161281467babc506ce31bb9385cd4..6cb361018b46f783bf03afbdb29dbe0da0300ebf 100644
--- a/drivers/spi/fsl_qspi.h
+++ b/drivers/spi/fsl_qspi.h
@@ -58,7 +58,12 @@ struct fsl_qspi_regs {
 
 #define QSPI_MCR_END_CFD_SHIFT		2
 #define QSPI_MCR_END_CFD_MASK		(3 << QSPI_MCR_END_CFD_SHIFT)
+#ifdef CONFIG_SYS_FSL_QSPI_AHB
+/* AHB needs 64bit operation */
+#define QSPI_MCR_END_CFD_LE		(3 << QSPI_MCR_END_CFD_SHIFT)
+#else
 #define QSPI_MCR_END_CFD_LE		(1 << QSPI_MCR_END_CFD_SHIFT)
+#endif
 #define QSPI_MCR_DDR_EN_SHIFT		7
 #define QSPI_MCR_DDR_EN_MASK		(1 << QSPI_MCR_DDR_EN_SHIFT)
 #define QSPI_MCR_CLR_RXF_SHIFT		10
@@ -69,6 +74,10 @@ struct fsl_qspi_regs {
 #define QSPI_MCR_MDIS_MASK		(1 << QSPI_MCR_MDIS_SHIFT)
 #define QSPI_MCR_RESERVED_SHIFT		16
 #define QSPI_MCR_RESERVED_MASK		(0xf << QSPI_MCR_RESERVED_SHIFT)
+#define QSPI_MCR_SWRSTHD_SHIFT		1
+#define QSPI_MCR_SWRSTHD_MASK		(1 << QSPI_MCR_SWRSTHD_SHIFT)
+#define QSPI_MCR_SWRSTSD_SHIFT		0
+#define QSPI_MCR_SWRSTSD_MASK		(1 << QSPI_MCR_SWRSTSD_SHIFT)
 
 #define QSPI_SMPR_HSENA_SHIFT		0
 #define QSPI_SMPR_HSENA_MASK		(1 << QSPI_SMPR_HSENA_SHIFT)
@@ -79,6 +88,12 @@ struct fsl_qspi_regs {
 #define QSPI_SMPR_DDRSMP_SHIFT		16
 #define QSPI_SMPR_DDRSMP_MASK		(7 << QSPI_SMPR_DDRSMP_SHIFT)
 
+#define QSPI_BUFXCR_INVALID_MSTRID	0xe
+#define QSPI_BUF3CR_ALLMST_SHIFT	31
+#define QSPI_BUF3CR_ALLMST_MASK		(1 << QSPI_BUF3CR_ALLMST_SHIFT)
+#define QSPI_BUF3CR_ADATSZ_SHIFT	8
+#define QSPI_BUF3CR_ADATSZ_MASK		(0xFF << QSPI_BUF3CR_ADATSZ_SHIFT)
+
 #define QSPI_BFGENCR_SEQID_SHIFT	12
 #define QSPI_BFGENCR_SEQID_MASK		(0xf << QSPI_BFGENCR_SEQID_SHIFT)
 #define QSPI_BFGENCR_PAR_EN_SHIFT	16