]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
mtd: spi-nor: Added dual parallel and stacked support
authorMichal Simek <michal.simek@xilinx.com>
Wed, 13 Sep 2017 12:37:18 +0000 (14:37 +0200)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 15 Mar 2018 14:17:22 +0000 (15:17 +0100)
Added the dual parallel and stacked configuration support
to the gqspi driver.

Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Reviewed-by: Harini Katakam <harinik@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/spi/spi-zynqmp-gqspi.c

index 305fffe2b10110d393b157e91f08b350a0183cb5..e6378d7a4304f4d8d9f743879f6b976ca56c8526 100644 (file)
@@ -153,6 +153,7 @@ enum mode_type {GQSPI_MODE_IO, GQSPI_MODE_DMA};
  * @dma_rx_bytes:      Remaining bytes to receive by DMA mode
  * @dma_addr:          DMA address after mapping the kernel buffer
  * @genfifoentry:      Used for storing the genfifoentry instruction.
+ * @isinstr:           To determine whether the transfer is instruction
  * @mode:              Defines the mode in which QSPI is operating
  */
 struct zynqmp_qspi {
@@ -170,6 +171,7 @@ struct zynqmp_qspi {
        u32 dma_rx_bytes;
        dma_addr_t dma_addr;
        u32 genfifoentry;
+       bool isinstr;
        enum mode_type mode;
 };
 
@@ -406,9 +408,24 @@ static void zynqmp_qspi_chipselect(struct spi_device *qspi, bool is_high)
        genfifoentry |= GQSPI_GENFIFO_MODE_SPI;
        genfifoentry |= xqspi->genfifobus;
 
+       if (qspi->master->flags & SPI_MASTER_BOTH_CS) {
+               zynqmp_gqspi_selectslave(xqspi,
+                       GQSPI_SELECT_FLASH_CS_BOTH,
+                       GQSPI_SELECT_FLASH_BUS_BOTH);
+       } else if (qspi->master->flags & SPI_MASTER_U_PAGE) {
+               zynqmp_gqspi_selectslave(xqspi,
+                       GQSPI_SELECT_FLASH_CS_UPPER,
+                       GQSPI_SELECT_FLASH_BUS_LOWER);
+       } else {
+               zynqmp_gqspi_selectslave(xqspi,
+                       GQSPI_SELECT_FLASH_CS_LOWER,
+                       GQSPI_SELECT_FLASH_BUS_LOWER);
+       }
+
        if (!is_high) {
                genfifoentry |= xqspi->genfifocs;
                genfifoentry |= GQSPI_GENFIFO_CS_SETUP;
+               xqspi->isinstr = true;
        } else {
                genfifoentry |= GQSPI_GENFIFO_CS_HOLD;
        }
@@ -555,7 +572,7 @@ static void zynqmp_qspi_readrxfifo(struct zynqmp_qspi *xqspi, u32 size)
        while ((count < size) && (xqspi->bytes_to_receive > 0)) {
                if (xqspi->bytes_to_receive >= 4) {
                        (*(u32 *) xqspi->rxbuf) =
-                       zynqmp_gqspi_read(xqspi, GQSPI_RXD_OFST);
+                               zynqmp_gqspi_read(xqspi, GQSPI_RXD_OFST);
                        xqspi->rxbuf += 4;
                        xqspi->bytes_to_receive -= 4;
                        count += 4;
@@ -665,6 +682,7 @@ static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id)
        if ((xqspi->bytes_to_receive == 0) && (xqspi->bytes_to_transfer == 0)
                        && ((status & GQSPI_IRQ_MASK) == GQSPI_IRQ_MASK)) {
                zynqmp_gqspi_write(xqspi, GQSPI_IDR_OFST, GQSPI_ISR_IDR_MASK);
+               xqspi->isinstr = false;
                spi_finalize_current_transfer(master);
                ret = IRQ_HANDLED;
        }
@@ -828,6 +846,10 @@ static int zynqmp_qspi_start_transfer(struct spi_master *master,
        genfifoentry |= xqspi->genfifocs;
        genfifoentry |= xqspi->genfifobus;
 
+       if ((!xqspi->isinstr) &&
+               (master->flags & SPI_MASTER_DATA_STRIPE))
+               genfifoentry |= GQSPI_GENFIFO_STRIPE;
+
        zynqmp_qspi_txrxsetup(xqspi, transfer, &genfifoentry);
 
        if (xqspi->mode == GQSPI_MODE_DMA)