spi: fsl_qspi: Enable Spansion S25FS-S family flashes

The flash type of LS2085AQDS QSPI is S25FS256S. It has special write
any device register command and read any device register command.
This patch enable support for those commands.

Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
Reviewed-by: York Sun <york.sun@nxp.com>
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index db7ebee..75cbab2 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -44,6 +44,8 @@
 #define SEQID_RDEAR		11
 #define SEQID_WREAR		12
 #endif
+#define SEQID_WRAR		13
+#define SEQID_RDAR		14
 
 /* QSPI CMD */
 #define QSPI_CMD_PP		0x02	/* Page program (up to 256 bytes) */
@@ -63,6 +65,10 @@
 #define	QSPI_CMD_BRRD		0x16	/* Bank register read */
 #define	QSPI_CMD_BRWR		0x17	/* Bank register write */
 
+/* Used for Spansion S25FS-S family flash only. */
+#define QSPI_CMD_RDAR		0x65	/* Read any device register */
+#define QSPI_CMD_WRAR		0x71	/* Write any device register */
+
 /* 4-byte address QSPI CMD - used on Spansion and some Macronix flashes */
 #define QSPI_CMD_FAST_READ_4B	0x0c    /* Read data bytes (high frequency) */
 #define QSPI_CMD_PP_4B		0x12    /* Page program (up to 256 bytes) */
@@ -317,6 +323,33 @@
 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
 		     PAD1(LUT_PAD1) | INSTR1(LUT_WRITE));
 #endif
+
+	/*
+	 * Read any device register.
+	 * Used for Spansion S25FS-S family flash only.
+	 */
+	lut_base = SEQID_RDAR * 4;
+	qspi_write32(priv->flags, &regs->lut[lut_base],
+		     OPRND0(QSPI_CMD_RDAR) | PAD0(LUT_PAD1) |
+		     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
+		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+	qspi_write32(priv->flags, &regs->lut[lut_base + 1],
+		     OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) |
+		     OPRND1(1) | PAD1(LUT_PAD1) |
+		     INSTR1(LUT_READ));
+
+	/*
+	 * Write any device register.
+	 * Used for Spansion S25FS-S family flash only.
+	 */
+	lut_base = SEQID_WRAR * 4;
+	qspi_write32(priv->flags, &regs->lut[lut_base],
+		     OPRND0(QSPI_CMD_WRAR) | PAD0(LUT_PAD1) |
+		     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
+		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+	qspi_write32(priv->flags, &regs->lut[lut_base + 1],
+		     OPRND0(1) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
+
 	/* Lock the LUT */
 	qspi_write32(priv->flags, &regs->lutkey, LUT_KEY_VALUE);
 	qspi_write32(priv->flags, &regs->lckcr, QSPI_LCKCR_LOCK);
@@ -510,7 +543,6 @@
 	qspi_write32(priv->flags, &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_priv *priv, u32 *rxbuf, u32 len)
 {
@@ -518,6 +550,12 @@
 	u32 mcr_reg, data;
 	int i, size;
 	u32 to_or_from;
+	u32 seqid;
+
+	if (priv->cur_seqid == QSPI_CMD_RDAR)
+		seqid = SEQID_RDAR;
+	else
+		seqid = SEQID_FAST_READ;
 
 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
 	qspi_write32(priv->flags, &regs->mcr,
@@ -536,7 +574,7 @@
 			RX_BUFFER_SIZE : len;
 
 		qspi_write32(priv->flags, &regs->ipcr,
-			     (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) |
+			     (seqid << QSPI_IPCR_SEQID_SHIFT) |
 			     size);
 		while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
 			;
@@ -548,7 +586,10 @@
 		while ((RX_BUFFER_SIZE >= size) && (size > 0)) {
 			data = qspi_read32(priv->flags, &regs->rbdr[i]);
 			data = qspi_endian_xchg(data);
-			memcpy(rxbuf, &data, 4);
+			if (size < 4)
+				memcpy(rxbuf, &data, size);
+			else
+				memcpy(rxbuf, &data, 4);
 			rxbuf++;
 			size -= 4;
 			i++;
@@ -560,7 +601,6 @@
 
 	qspi_write32(priv->flags, &regs->mcr, mcr_reg);
 }
-#endif
 
 static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len)
 {
@@ -601,6 +641,8 @@
 
 	/* Default is page programming */
 	seqid = SEQID_PP;
+	if (priv->cur_seqid == QSPI_CMD_WRAR)
+		seqid = SEQID_WRAR;
 #ifdef CONFIG_SPI_FLASH_BAR
 	if (priv->cur_seqid == QSPI_CMD_BRWR)
 		seqid = SEQID_BRWR;
@@ -725,13 +767,15 @@
 			return 0;
 		}
 
-		if (priv->cur_seqid == QSPI_CMD_FAST_READ) {
+		if (priv->cur_seqid == QSPI_CMD_FAST_READ ||
+		    priv->cur_seqid == QSPI_CMD_RDAR) {
 			priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
 		} else if ((priv->cur_seqid == QSPI_CMD_SE) ||
 			   (priv->cur_seqid == QSPI_CMD_BE_4K)) {
 			priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
 			qspi_op_erase(priv);
-		} else if (priv->cur_seqid == QSPI_CMD_PP) {
+		} else if (priv->cur_seqid == QSPI_CMD_PP ||
+			   priv->cur_seqid == QSPI_CMD_WRAR) {
 			wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK;
 		} else if ((priv->cur_seqid == QSPI_CMD_BRWR) ||
 			 (priv->cur_seqid == QSPI_CMD_WREAR)) {
@@ -748,6 +792,8 @@
 #else
 			qspi_op_read(priv, din, bytes);
 #endif
+		} else if (priv->cur_seqid == QSPI_CMD_RDAR) {
+			qspi_op_read(priv, din, bytes);
 		} else if (priv->cur_seqid == QSPI_CMD_RDID)
 			qspi_op_rdid(priv, din, bytes);
 		else if (priv->cur_seqid == QSPI_CMD_RDSR)