[PATCH 0/4] Xilinx zynq_qspi updates

This patch series does below things - Add child preprobe function - Use dummy buswidth in dummy byte calculation - Add support for zynq_qspi_mem_exec_op - Fix qspi speed issue
Ashok Reddy Soma (2): spi: zynq_qspi: Add support for zynq_qspi_mem_exec_op spi: zynq_qspi: Fix programming qspi speed
Siva Durga Prasad Paladugu (1): spi: zynq_qspi: Add child pre probe function
T Karthik Reddy (1): spi: zynq_qspi: Use dummy buswidth in dummy byte calculation
drivers/spi/zynq_qspi.c | 73 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 8 deletions(-)

From: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com
Add child pre probe function in the driver. Update max_hz of priv from spi_slave structure.
Signed-off-by: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com Signed-off-by: Ashok Reddy Soma ashok.reddy.soma@xilinx.com ---
drivers/spi/zynq_qspi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index b69d992b28..066a0c6002 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -94,6 +94,7 @@ struct zynq_qspi_priv { u8 mode; u8 fifo_depth; u32 freq; /* required frequency */ + u32 max_hz; const void *tx_buf; void *rx_buf; unsigned len; @@ -174,6 +175,16 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv) writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, ®s->enr); }
+static int zynq_qspi_child_pre_probe(struct udevice *bus) +{ + struct spi_slave *slave = dev_get_parent_priv(bus); + struct zynq_qspi_priv *priv = dev_get_priv(bus->parent); + + priv->max_hz = slave->max_hz; + + return 0; +} + static int zynq_qspi_probe(struct udevice *bus) { struct zynq_qspi_plat *plat = dev_get_plat(bus); @@ -746,4 +757,5 @@ U_BOOT_DRIVER(zynq_qspi) = { .plat_auto = sizeof(struct zynq_qspi_plat), .priv_auto = sizeof(struct zynq_qspi_priv), .probe = zynq_qspi_probe, + .child_pre_probe = zynq_qspi_child_pre_probe, };

From: T Karthik Reddy t.karthik.reddy@xilinx.com
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 ---
drivers/spi/zynq_qspi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 066a0c6002..b138c3c38a 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -679,6 +679,7 @@ static int zynq_qspi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) { int op_len, pos = 0, ret, i; + u32 dummy_bytes = 0; unsigned int flag = 0; const u8 *tx_buf = NULL; u8 *rx_buf = NULL; @@ -691,6 +692,11 @@ static int zynq_qspi_exec_op(struct spi_slave *slave, }
op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; + if (op->dummy.nbytes) { + op_len = op->cmd.nbytes + op->addr.nbytes + + op->dummy.nbytes / op->dummy.buswidth; + dummy_bytes = op->dummy.nbytes / op->dummy.buswidth; + }
u8 op_buf[op_len];
@@ -704,8 +710,8 @@ static int zynq_qspi_exec_op(struct spi_slave *slave, pos += op->addr.nbytes; }
- if (op->dummy.nbytes) - memset(op_buf + pos, 0xff, op->dummy.nbytes); + if (dummy_bytes) + memset(op_buf + pos, 0xff, dummy_bytes);
/* 1st transfer: opcode + address + dummy cycles */ /* Make sure to set END bit if no tx or rx data messages follow */

Add support_ops function zynq_qspi_mem_exec_op 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.
Signed-off-by: Ashok Reddy Soma ashok.reddy.soma@xilinx.com ---
drivers/spi/zynq_qspi.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index b138c3c38a..52db7b3f21 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -736,8 +736,50 @@ static int zynq_qspi_exec_op(struct spi_slave *slave, return 0; }
+static int zynq_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 zynq_qspi_mem_exec_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + if (zynq_qspi_check_buswidth(slave, op->cmd.buswidth)) + return false; + + if (op->addr.nbytes && + zynq_qspi_check_buswidth(slave, op->addr.buswidth)) + return false; + + if (op->dummy.nbytes && + zynq_qspi_check_buswidth(slave, op->dummy.buswidth)) + return false; + + if (op->data.dir != SPI_MEM_NO_DATA && + zynq_qspi_check_buswidth(slave, op->data.buswidth)) + return false; + + return true; +} + static const struct spi_controller_mem_ops zynq_qspi_mem_ops = { .exec_op = zynq_qspi_exec_op, + .supports_op = zynq_qspi_mem_exec_op, };
static const struct dm_spi_ops zynq_qspi_ops = {

When programming qspi flash speed we need to check the requested flash speed not to exceed the spi max frequency. In the current implementation we are checking qspi ref clk instead. This commit fixes the issue by checking the requested speed and programs the specified max frequency.
Signed-off-by: Ashok Reddy Soma ashok.reddy.soma@xilinx.com ---
drivers/spi/zynq_qspi.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 52db7b3f21..00e3ffcd1d 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -622,15 +622,12 @@ static int zynq_qspi_set_speed(struct udevice *bus, uint speed) uint32_t confr; u8 baud_rate_val = 0;
- if (speed > plat->frequency) - speed = plat->frequency; + if (!speed || speed > priv->max_hz) + speed = priv->max_hz;
/* Set the clock frequency */ confr = readl(®s->cr); - if (speed == 0) { - /* Set baudrate x8, if the freq is 0 */ - baud_rate_val = 0x2; - } else if (plat->speed_hz != speed) { + if (plat->speed_hz != speed) { while ((baud_rate_val < ZYNQ_QSPI_CR_BAUD_MAX) && ((plat->frequency / (2 << baud_rate_val)) > speed))

On 7/15/22 16:01, Ashok Reddy Soma wrote:
This patch series does below things
- Add child preprobe function
- Use dummy buswidth in dummy byte calculation
- Add support for zynq_qspi_mem_exec_op
- Fix qspi speed issue
Ashok Reddy Soma (2): spi: zynq_qspi: Add support for zynq_qspi_mem_exec_op spi: zynq_qspi: Fix programming qspi speed
Siva Durga Prasad Paladugu (1): spi: zynq_qspi: Add child pre probe function
T Karthik Reddy (1): spi: zynq_qspi: Use dummy buswidth in dummy byte calculation
drivers/spi/zynq_qspi.c | 73 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 8 deletions(-)
Applied. M
participants (2)
-
Ashok Reddy Soma
-
Michal Simek