]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
spi: xilinx_spi: Add support ops to axi qspi driver
authorT Karthik Reddy <t.karthik.reddy@xilinx.com>
Sat, 16 Jul 2022 06:58:47 +0000 (12:28 +0530)
committerMichal Simek <michal.simek@amd.com>
Tue, 26 Jul 2022 07:34:21 +0000 (09:34 +0200)
Add support_ops function to check controller supported operations by
spi-mem framework. Current default support ops function does not allow
dummy buswidth no more than 1, unless we are using buswidth is 4 for TX.
In order to support dummy buswidth > 1 by spi-nor framework we are adding
explicit support_ops to check controller supported operations.

Fix dummy bytes calculation incase of valid dummy bytes when dummy
buswidth is > 1. Current dummy bytes calculation does not provide
correct dummy values for dummy buswidth > 1.

Signed-off-by: T Karthik Reddy <t.karthik.reddy@xilinx.com>
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Link: https://lore.kernel.org/r/1657954727-31972-3-git-send-email-ashok.reddy.soma@xilinx.com
Signed-off-by: Michal Simek <michal.simek@amd.com>
drivers/spi/xilinx_spi.c

index 09d4b01631ffe3fbdfcba72db5dce1bb2ed78850..4e9115dafee8dd15916f4cfa29024ae4efa75338 100644 (file)
@@ -320,7 +320,9 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi,
                        goto done;
        }
        if (op->dummy.nbytes) {
-               dummy_len = op->dummy.nbytes * op->data.buswidth;
+               dummy_len = (op->dummy.nbytes * op->data.buswidth) /
+                            op->dummy.buswidth;
+
                ret = start_transfer(spi, NULL, NULL, dummy_len);
                if (ret)
                        goto done;
@@ -342,6 +344,47 @@ done:
        return ret;
 }
 
+static int xilinx_qspi_check_buswidth(struct spi_slave *slave, u8 width)
+{
+       u32 mode = slave->mode;
+
+       switch (width) {
+       case 1:
+               return 0;
+       case 2:
+               if (mode & SPI_RX_DUAL)
+                       return 0;
+               break;
+       case 4:
+               if (mode & SPI_RX_QUAD)
+                       return 0;
+               break;
+       }
+
+       return -EOPNOTSUPP;
+}
+
+bool xilinx_qspi_mem_exec_op(struct spi_slave *slave,
+                            const struct spi_mem_op *op)
+{
+       if (xilinx_qspi_check_buswidth(slave, op->cmd.buswidth))
+               return false;
+
+       if (op->addr.nbytes &&
+           xilinx_qspi_check_buswidth(slave, op->addr.buswidth))
+               return false;
+
+       if (op->dummy.nbytes &&
+           xilinx_qspi_check_buswidth(slave, op->dummy.buswidth))
+               return false;
+
+       if (op->data.dir != SPI_MEM_NO_DATA &&
+           xilinx_qspi_check_buswidth(slave, op->data.buswidth))
+               return false;
+
+       return true;
+}
+
 static int xilinx_spi_set_speed(struct udevice *bus, uint speed)
 {
        struct xilinx_spi_priv *priv = dev_get_priv(bus);
@@ -379,6 +422,7 @@ static int xilinx_spi_set_mode(struct udevice *bus, uint mode)
 
 static const struct spi_controller_mem_ops xilinx_spi_mem_ops = {
        .exec_op = xilinx_spi_mem_exec_op,
+       .supports_op = xilinx_qspi_mem_exec_op,
 };
 
 static const struct dm_spi_ops xilinx_spi_ops = {