+#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(®s->mcr);
+ reg |= QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK;
+ qspi_write32(®s->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(®s->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(®s->mcr);
+
+ qspi_write32(®s->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(®s->mcr, mcr_reg);
+}
+
+static void qspi_enable_ddr_mode(struct fsl_qspi_regs *regs)
+{
+ u32 reg, reg2;
+
+ reg = qspi_read32(®s->mcr);
+ /* Disable the module */
+ qspi_write32(®s->mcr, reg | QSPI_MCR_MDIS_MASK);
+
+ /* Set the Sampling Register for DDR */
+ reg2 = qspi_read32(®s->smpr);
+ reg2 &= ~QSPI_SMPR_DDRSMP_MASK;
+ reg2 |= (2 << QSPI_SMPR_DDRSMP_SHIFT);
+ qspi_write32(®s->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(®s->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(®s->buf0cr, QSPI_BUFXCR_INVALID_MSTRID);
+ qspi_write32(®s->buf1cr, QSPI_BUFXCR_INVALID_MSTRID);
+ qspi_write32(®s->buf2cr, QSPI_BUFXCR_INVALID_MSTRID);
+ qspi_write32(®s->buf3cr, QSPI_BUF3CR_ALLMST_MASK |
+ (0x80 << QSPI_BUF3CR_ADATSZ_SHIFT));
+
+ /* We only use the buffer3 */
+ qspi_write32(®s->buf0ind, 0);
+ qspi_write32(®s->buf1ind, 0);
+ qspi_write32(®s->buf2ind, 0);
+
+ /*
+ * Set the default lut sequence for AHB Read.
+ * Parallel mode is disabled.
+ */
+ qspi_write32(®s->bfgencr,
+ SEQID_FAST_READ << QSPI_BFGENCR_SEQID_SHIFT);
+
+ /*Enable DDR Mode*/
+ qspi_enable_ddr_mode(regs);
+}
+#endif
+