diff options
author | T Karthik Reddy <t.karthik.reddy@xilinx.com> | 2022-07-16 12:28:47 +0530 |
---|---|---|
committer | Michal Simek <michal.simek@amd.com> | 2022-07-26 09:34:21 +0200 |
commit | 557832bd88351ffc0b8e43720b98700fe74f68b2 (patch) | |
tree | 036746d268118f05a1e209388c6ccf6eb5fa18c2 /drivers/spi/xilinx_spi.c | |
parent | f2dd6599df65dd307d7170f1b2fc0d38eb44ad75 (diff) |
spi: xilinx_spi: Add support ops to axi qspi driver
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>
Diffstat (limited to 'drivers/spi/xilinx_spi.c')
-rw-r--r-- | drivers/spi/xilinx_spi.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 09d4b01631..4e9115dafe 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -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 = { |