Merge branch 'spi-4.17' into spi-4.18 for the merge window
[platform/kernel/linux-starfive.git] / drivers / spi / spi-bcm-qspi.c
index 6573152..8612525 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
 #include <linux/sysfs.h>
 #include <linux/types.h>
 #include "spi-bcm-qspi.h"
@@ -215,10 +216,10 @@ struct bcm_qspi {
        int bspi_maj_rev;
        int bspi_min_rev;
        int bspi_enabled;
-       struct spi_flash_read_message *bspi_rf_msg;
-       u32 bspi_rf_msg_idx;
-       u32 bspi_rf_msg_len;
-       u32 bspi_rf_msg_status;
+       const struct spi_mem_op *bspi_rf_op;
+       u32 bspi_rf_op_idx;
+       u32 bspi_rf_op_len;
+       u32 bspi_rf_op_status;
        struct bcm_xfer_mode xfer_mode;
        u32 s3_strap_override_ctrl;
        bool bspi_mode;
@@ -313,26 +314,26 @@ static inline void bcm_qspi_bspi_lr_clear(struct bcm_qspi *qspi)
 
 static void bcm_qspi_bspi_lr_data_read(struct bcm_qspi *qspi)
 {
-       u32 *buf = (u32 *)qspi->bspi_rf_msg->buf;
+       u32 *buf = (u32 *)qspi->bspi_rf_op->data.buf.in;
        u32 data = 0;
 
-       dev_dbg(&qspi->pdev->dev, "xfer %p rx %p rxlen %d\n", qspi->bspi_rf_msg,
-               qspi->bspi_rf_msg->buf, qspi->bspi_rf_msg_len);
+       dev_dbg(&qspi->pdev->dev, "xfer %p rx %p rxlen %d\n", qspi->bspi_rf_op,
+               qspi->bspi_rf_op->data.buf.in, qspi->bspi_rf_op_len);
        while (!bcm_qspi_bspi_lr_is_fifo_empty(qspi)) {
                data = bcm_qspi_bspi_lr_read_fifo(qspi);
-               if (likely(qspi->bspi_rf_msg_len >= 4) &&
+               if (likely(qspi->bspi_rf_op_len >= 4) &&
                    IS_ALIGNED((uintptr_t)buf, 4)) {
-                       buf[qspi->bspi_rf_msg_idx++] = data;
-                       qspi->bspi_rf_msg_len -= 4;
+                       buf[qspi->bspi_rf_op_idx++] = data;
+                       qspi->bspi_rf_op_len -= 4;
                } else {
                        /* Read out remaining bytes, make sure*/
-                       u8 *cbuf = (u8 *)&buf[qspi->bspi_rf_msg_idx];
+                       u8 *cbuf = (u8 *)&buf[qspi->bspi_rf_op_idx];
 
                        data = cpu_to_le32(data);
-                       while (qspi->bspi_rf_msg_len) {
+                       while (qspi->bspi_rf_op_len) {
                                *cbuf++ = (u8)data;
                                data >>= 8;
-                               qspi->bspi_rf_msg_len--;
+                               qspi->bspi_rf_op_len--;
                        }
                }
        }
@@ -349,14 +350,12 @@ static void bcm_qspi_bspi_set_xfer_params(struct bcm_qspi *qspi, u8 cmd_byte,
 }
 
 static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi,
-                                      struct spi_flash_read_message *msg,
-                                      int hp)
+                                      const struct spi_mem_op *op, int hp)
 {
        int bpc = 0, bpp = 0;
-       u8 command = msg->read_opcode;
-       int width  = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
-       int addrlen = msg->addr_width;
-       int addr_nbits = msg->addr_nbits ? msg->addr_nbits : SPI_NBITS_SINGLE;
+       u8 command = op->cmd.opcode;
+       int width  = op->cmd.buswidth ? op->cmd.buswidth : SPI_NBITS_SINGLE;
+       int addrlen = op->addr.nbytes * 8;
        int flex_mode = 1;
 
        dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n",
@@ -365,7 +364,7 @@ static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi,
        if (addrlen == BSPI_ADDRLEN_4BYTES)
                bpp = BSPI_BPP_ADDR_SELECT_MASK;
 
-       bpp |= msg->dummy_bytes * (8/addr_nbits);
+       bpp |= (op->dummy.nbytes * 8) / op->dummy.buswidth;
 
        switch (width) {
        case SPI_NBITS_SINGLE:
@@ -397,11 +396,10 @@ static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi,
 }
 
 static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi,
-                                     struct spi_flash_read_message *msg,
-                                     int hp)
+                                     const struct spi_mem_op *op, int hp)
 {
-       int width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
-       int addrlen = msg->addr_width;
+       int width = op->data.buswidth ? op->data.buswidth : SPI_NBITS_SINGLE;
+       int addrlen = op->addr.nbytes;
        u32 data = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL);
 
        dev_dbg(&qspi->pdev->dev, "set override mode w %x addrlen %x hp %d\n",
@@ -437,17 +435,17 @@ static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi,
        /* set the override mode */
        data |= BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE;
        bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, data);
-       bcm_qspi_bspi_set_xfer_params(qspi, msg->read_opcode, 0, 0, 0);
+       bcm_qspi_bspi_set_xfer_params(qspi, op->cmd.opcode, 0, 0, 0);
 
        return 0;
 }
 
 static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi,
-                                 struct spi_flash_read_message *msg, int hp)
+                                 const struct spi_mem_op *op, int hp)
 {
        int error = 0;
-       int width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
-       int addrlen = msg->addr_width;
+       int width = op->data.buswidth ? op->data.buswidth : SPI_NBITS_SINGLE;
+       int addrlen = op->addr.nbytes;
 
        /* default mode */
        qspi->xfer_mode.flex_mode = true;
@@ -460,12 +458,12 @@ static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi,
                if (val & mask || qspi->s3_strap_override_ctrl & mask) {
                        qspi->xfer_mode.flex_mode = false;
                        bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0);
-                       error = bcm_qspi_bspi_set_override(qspi, msg, hp);
+                       error = bcm_qspi_bspi_set_override(qspi, op, hp);
                }
        }
 
        if (qspi->xfer_mode.flex_mode)
-               error = bcm_qspi_bspi_set_flex_mode(qspi, msg, hp);
+               error = bcm_qspi_bspi_set_flex_mode(qspi, op, hp);
 
        if (error) {
                dev_warn(&qspi->pdev->dev,
@@ -802,19 +800,20 @@ done:
        return slot;
 }
 
-static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
-                                   struct spi_flash_read_message *msg)
+static int bcm_qspi_bspi_exec_mem_op(struct spi_device *spi,
+                                    const struct spi_mem_op *op)
 {
        struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
-       u32 addr = 0, len, rdlen, len_words;
+       u32 addr = 0, len, rdlen, len_words, from = 0;
        int ret = 0;
        unsigned long timeo = msecs_to_jiffies(100);
        struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
 
        if (bcm_qspi_bspi_ver_three(qspi))
-               if (msg->addr_width == BSPI_ADDRLEN_4BYTES)
+               if (op->addr.nbytes == BSPI_ADDRLEN_4BYTES)
                        return -EIO;
 
+       from = op->addr.val;
        bcm_qspi_chip_select(qspi, spi->chip_select);
        bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
 
@@ -823,15 +822,15 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
         * the upper address byte to bspi
         */
        if (bcm_qspi_bspi_ver_three(qspi) == false) {
-               addr = msg->from & 0xff000000;
+               addr = from & 0xff000000;
                bcm_qspi_write(qspi, BSPI,
                               BSPI_BSPI_FLASH_UPPER_ADDR_BYTE, addr);
        }
 
        if (!qspi->xfer_mode.flex_mode)
-               addr = msg->from;
+               addr = from;
        else
-               addr = msg->from & 0x00ffffff;
+               addr = from & 0x00ffffff;
 
        if (bcm_qspi_bspi_ver_three(qspi) == true)
                addr = (addr + 0xc00000) & 0xffffff;
@@ -840,8 +839,8 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
         * read into the entire buffer by breaking the reads
         * into RAF buffer read lengths
         */
-       len = msg->len;
-       qspi->bspi_rf_msg_idx = 0;
+       len = op->data.nbytes;
+       qspi->bspi_rf_op_idx = 0;
 
        do {
                if (len > BSPI_READ_LENGTH)
@@ -852,9 +851,9 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
                reinit_completion(&qspi->bspi_done);
                bcm_qspi_enable_bspi(qspi);
                len_words = (rdlen + 3) >> 2;
-               qspi->bspi_rf_msg = msg;
-               qspi->bspi_rf_msg_status = 0;
-               qspi->bspi_rf_msg_len = rdlen;
+               qspi->bspi_rf_op = op;
+               qspi->bspi_rf_op_status = 0;
+               qspi->bspi_rf_op_len = rdlen;
                dev_dbg(&qspi->pdev->dev,
                        "bspi xfr addr 0x%x len 0x%x", addr, rdlen);
                bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr);
@@ -879,7 +878,6 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
                }
 
                /* set msg return length */
-               msg->retlen += rdlen;
                addr += rdlen;
                len -= rdlen;
        } while (len);
@@ -914,61 +912,63 @@ static int bcm_qspi_transfer_one(struct spi_master *master,
        return 0;
 }
 
-static int bcm_qspi_mspi_flash_read(struct spi_device *spi,
-                                   struct spi_flash_read_message *msg)
+static int bcm_qspi_mspi_exec_mem_op(struct spi_device *spi,
+                                    const struct spi_mem_op *op)
 {
-       struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
+       struct spi_master *master = spi->master;
+       struct bcm_qspi *qspi = spi_master_get_devdata(master);
        struct spi_transfer t[2];
-       u8 cmd[6];
-       int ret;
+       u8 cmd[6] = { };
+       int ret, i;
 
        memset(cmd, 0, sizeof(cmd));
        memset(t, 0, sizeof(t));
 
        /* tx */
        /* opcode is in cmd[0] */
-       cmd[0] = msg->read_opcode;
-       cmd[1] = msg->from >> (msg->addr_width * 8 -  8);
-       cmd[2] = msg->from >> (msg->addr_width * 8 - 16);
-       cmd[3] = msg->from >> (msg->addr_width * 8 - 24);
-       cmd[4] = msg->from >> (msg->addr_width * 8 - 32);
+       cmd[0] = op->cmd.opcode;
+       for (i = 0; i < op->addr.nbytes; i++)
+               cmd[1 + i] = op->addr.val >> (8 * (op->addr.nbytes - i - 1));
+
        t[0].tx_buf = cmd;
-       t[0].len = msg->addr_width + msg->dummy_bytes + 1;
+       t[0].len = op->addr.nbytes + op->dummy.nbytes + 1;
        t[0].bits_per_word = spi->bits_per_word;
-       t[0].tx_nbits = msg->opcode_nbits;
+       t[0].tx_nbits = op->cmd.buswidth;
        /* lets mspi know that this is not last transfer */
        qspi->trans_pos.mspi_last_trans = false;
-       ret = bcm_qspi_transfer_one(spi->master, spi, &t[0]);
+       ret = bcm_qspi_transfer_one(master, spi, &t[0]);
 
        /* rx */
        qspi->trans_pos.mspi_last_trans = true;
        if (!ret) {
                /* rx */
-               t[1].rx_buf = msg->buf;
-               t[1].len = msg->len;
-               t[1].rx_nbits =  msg->data_nbits;
+               t[1].rx_buf = op->data.buf.in;
+               t[1].len = op->data.nbytes;
+               t[1].rx_nbits =  op->data.buswidth;
                t[1].bits_per_word = spi->bits_per_word;
-               ret = bcm_qspi_transfer_one(spi->master, spi, &t[1]);
+               ret = bcm_qspi_transfer_one(master, spi, &t[1]);
        }
 
-       if (!ret)
-               msg->retlen = msg->len;
-
        return ret;
 }
 
-static int bcm_qspi_flash_read(struct spi_device *spi,
-                              struct spi_flash_read_message *msg)
+static int bcm_qspi_exec_mem_op(struct spi_mem *mem,
+                               const struct spi_mem_op *op)
 {
+       struct spi_device *spi = mem->spi;
        struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
        int ret = 0;
        bool mspi_read = false;
-       u32 addr, len;
+       u32 addr = 0, len;
        u_char *buf;
 
-       buf = msg->buf;
-       addr = msg->from;
-       len = msg->len;
+       if (!op->data.nbytes || !op->addr.nbytes || op->addr.nbytes > 4 ||
+           op->data.dir != SPI_MEM_DATA_IN)
+               return -ENOTSUPP;
+
+       buf = op->data.buf.in;
+       addr = op->addr.val;
+       len = op->data.nbytes;
 
        if (bcm_qspi_bspi_ver_three(qspi) == true) {
                /*
@@ -990,12 +990,12 @@ static int bcm_qspi_flash_read(struct spi_device *spi,
                mspi_read = true;
 
        if (mspi_read)
-               return bcm_qspi_mspi_flash_read(spi, msg);
+               return bcm_qspi_mspi_exec_mem_op(spi, op);
 
-       ret = bcm_qspi_bspi_set_mode(qspi, msg, -1);
+       ret = bcm_qspi_bspi_set_mode(qspi, op, -1);
 
        if (!ret)
-               ret = bcm_qspi_bspi_flash_read(spi, msg);
+               ret = bcm_qspi_bspi_exec_mem_op(spi, op);
 
        return ret;
 }
@@ -1034,10 +1034,10 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
        struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
        u32 status = qspi_dev_id->irqp->mask;
 
-       if (qspi->bspi_enabled && qspi->bspi_rf_msg) {
+       if (qspi->bspi_enabled && qspi->bspi_rf_op) {
                bcm_qspi_bspi_lr_data_read(qspi);
-               if (qspi->bspi_rf_msg_len == 0) {
-                       qspi->bspi_rf_msg = NULL;
+               if (qspi->bspi_rf_op_len == 0) {
+                       qspi->bspi_rf_op = NULL;
                        if (qspi->soc_intc) {
                                /* disable soc BSPI interrupt */
                                soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE,
@@ -1046,7 +1046,7 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
                                status = INTR_BSPI_LR_SESSION_DONE_MASK;
                        }
 
-                       if (qspi->bspi_rf_msg_status)
+                       if (qspi->bspi_rf_op_status)
                                bcm_qspi_bspi_lr_clear(qspi);
                        else
                                bcm_qspi_bspi_flush_prefetch_buffers(qspi);
@@ -1058,7 +1058,7 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
        }
 
        status &= INTR_BSPI_LR_SESSION_DONE_MASK;
-       if (qspi->bspi_enabled && status && qspi->bspi_rf_msg_len == 0)
+       if (qspi->bspi_enabled && status && qspi->bspi_rf_op_len == 0)
                complete(&qspi->bspi_done);
 
        return IRQ_HANDLED;
@@ -1071,7 +1071,7 @@ static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
        struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
 
        dev_err(&qspi->pdev->dev, "BSPI INT error\n");
-       qspi->bspi_rf_msg_status = -EIO;
+       qspi->bspi_rf_op_status = -EIO;
        if (qspi->soc_intc)
                /* clear soc interrupt */
                soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_ERR);
@@ -1194,6 +1194,10 @@ static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi)
 
 }
 
+static const struct spi_controller_mem_ops bcm_qspi_mem_ops = {
+       .exec_op = bcm_qspi_exec_mem_op,
+};
+
 static const struct of_device_id bcm_qspi_of_match[] = {
        { .compatible = "brcm,spi-bcm-qspi" },
        {},
@@ -1236,7 +1240,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
        master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_RX_DUAL | SPI_RX_QUAD;
        master->setup = bcm_qspi_setup;
        master->transfer_one = bcm_qspi_transfer_one;
-       master->spi_flash_read = bcm_qspi_flash_read;
+       master->mem_ops = &bcm_qspi_mem_ops;
        master->cleanup = bcm_qspi_cleanup;
        master->dev.of_node = dev->of_node;
        master->num_chipselect = NUM_CHIPSELECT;