Merge tag 'fs.idmapped.v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/braune...
[linux-2.6-microblaze.git] / drivers / spi / spi-mxic.c
index 96b4182..4588994 100644 (file)
@@ -335,8 +335,10 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf,
 static bool mxic_spi_mem_supports_op(struct spi_mem *mem,
                                     const struct spi_mem_op *op)
 {
-       if (op->data.buswidth > 4 || op->addr.buswidth > 4 ||
-           op->dummy.buswidth > 4 || op->cmd.buswidth > 4)
+       bool all_false;
+
+       if (op->data.buswidth > 8 || op->addr.buswidth > 8 ||
+           op->dummy.buswidth > 8 || op->cmd.buswidth > 8)
                return false;
 
        if (op->data.nbytes && op->dummy.nbytes &&
@@ -346,7 +348,13 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem,
        if (op->addr.nbytes > 7)
                return false;
 
-       return spi_mem_default_supports_op(mem, op);
+       all_false = !op->cmd.dtr && !op->addr.dtr && !op->dummy.dtr &&
+                   !op->data.dtr;
+
+       if (all_false)
+               return spi_mem_default_supports_op(mem, op);
+       else
+               return spi_mem_dtr_supports_op(mem, op);
 }
 
 static int mxic_spi_mem_exec_op(struct spi_mem *mem,
@@ -355,14 +363,15 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
        struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master);
        int nio = 1, i, ret;
        u32 ss_ctrl;
-       u8 addr[8];
-       u8 opcode = op->cmd.opcode;
+       u8 addr[8], cmd[2];
 
        ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz);
        if (ret)
                return ret;
 
-       if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD))
+       if (mem->spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL))
+               nio = 8;
+       else if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD))
                nio = 4;
        else if (mem->spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL))
                nio = 2;
@@ -374,19 +383,26 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
               mxic->regs + HC_CFG);
        writel(HC_EN_BIT, mxic->regs + HC_EN);
 
-       ss_ctrl = OP_CMD_BYTES(1) | OP_CMD_BUSW(fls(op->cmd.buswidth) - 1);
+       ss_ctrl = OP_CMD_BYTES(op->cmd.nbytes) |
+                 OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) |
+                 (op->cmd.dtr ? OP_CMD_DDR : 0);
 
        if (op->addr.nbytes)
                ss_ctrl |= OP_ADDR_BYTES(op->addr.nbytes) |
-                          OP_ADDR_BUSW(fls(op->addr.buswidth) - 1);
+                          OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) |
+                          (op->addr.dtr ? OP_ADDR_DDR : 0);
 
        if (op->dummy.nbytes)
                ss_ctrl |= OP_DUMMY_CYC(op->dummy.nbytes);
 
        if (op->data.nbytes) {
-               ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1);
-               if (op->data.dir == SPI_MEM_DATA_IN)
+               ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) |
+                          (op->data.dtr ? OP_DATA_DDR : 0);
+               if (op->data.dir == SPI_MEM_DATA_IN) {
                        ss_ctrl |= OP_READ;
+                       if (op->data.dtr)
+                               ss_ctrl |= OP_DQS_EN;
+               }
        }
 
        writel(ss_ctrl, mxic->regs + SS_CTRL(mem->spi->chip_select));
@@ -394,7 +410,10 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
        writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT,
               mxic->regs + HC_CFG);
 
-       ret = mxic_spi_data_xfer(mxic, &opcode, NULL, 1);
+       for (i = 0; i < op->cmd.nbytes; i++)
+               cmd[i] = op->cmd.opcode >> (8 * (op->cmd.nbytes - i - 1));
+
+       ret = mxic_spi_data_xfer(mxic, cmd, NULL, op->cmd.nbytes);
        if (ret)
                goto out;
 
@@ -567,7 +586,8 @@ static int mxic_spi_probe(struct platform_device *pdev)
        master->bits_per_word_mask = SPI_BPW_MASK(8);
        master->mode_bits = SPI_CPOL | SPI_CPHA |
                        SPI_RX_DUAL | SPI_TX_DUAL |
-                       SPI_RX_QUAD | SPI_TX_QUAD;
+                       SPI_RX_QUAD | SPI_TX_QUAD |
+                       SPI_RX_OCTAL | SPI_TX_OCTAL;
 
        mxic_spi_hw_init(mxic);