[PATCH v3 6/6] spi: zynq_qspi: Add parallel memories support in QSPI driver

Stefan Herbrechtsmeier stefan.herbrechtsmeier-oss at weidmueller.com
Fri Oct 20 09:16:13 CEST 2023


Hi,

Am 20.10.2023 um 05:18 schrieb Venkatesh Yadav Abbarapu:
> Add support for parallel memories in zynq_qspi.c driver. In case of
> parallel memories STRIPE bit is set and sent to the qspi ip, which will
> send data bits to both the flashes in parallel. However for few commands
> we should not use stripe, instead send same data to both the flashes.
> Those commands are exclueded by using zynqmp_qspi_update_stripe().
>
> Also update copyright info for this file.
>
> Signed-off-by: Ashok Reddy Soma<ashok.reddy.soma at amd.com>
> Signed-off-by: Venkatesh Yadav Abbarapu<venkatesh.abbarapu at amd.com>
> ---
>   drivers/spi/zynq_qspi.c | 140 ++++++++++++++++++++++++++++++++++++----
>   include/spi.h           |   4 ++
>   2 files changed, 131 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
> index 069d2a77de..3471c301bf 100644
> --- a/drivers/spi/zynq_qspi.c
> +++ b/drivers/spi/zynq_qspi.c

[snip]


> @@ -112,7 +136,6 @@ static int zynq_qspi_of_to_plat(struct udevice *bus)
>   
>   	plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
>   							      node, "reg");
> -

Unrelated?

>   	return 0;
>   }
>   

[snip]

> @@ -688,6 +788,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;
> +	}

This is wrong because the core already divide the dummy.nbytes by the 
bus width:

(nor->read_dummy * op.dummy.buswidth) / 8


>   
>   	u8 op_buf[op_len];
>   
> @@ -701,8 +806,11 @@ 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);
> +
> +	if (slave->flags & SPI_XFER_U_PAGE)
> +		flag |= SPI_XFER_U_PAGE;
>   
>   	/* 1st transfer: opcode + address + dummy cycles */
>   	/* Make sure to set END bit if no tx or rx data messages follow */
> @@ -714,6 +822,9 @@ static int zynq_qspi_exec_op(struct spi_slave *slave,
>   	if (ret)
>   		return ret;
>   
> +	slave->dummy_bytes = 0;

What is the purpose of this variable?

> +	priv->is_strip = update_stripe(op);
> +
>   	/* 2nd transfer: rx or tx data path */
>   	if (tx_buf || rx_buf) {
>   		ret = zynq_qspi_xfer(slave->dev, op->data.nbytes * 8, tx_buf,
> @@ -722,6 +833,9 @@ static int zynq_qspi_exec_op(struct spi_slave *slave,
>   			return ret;
>   	}
>   
> +	priv->is_parallel = false;
> +	priv->is_stacked = false;
> +	slave->flags &= ~SPI_XFER_MASK;
>   	spi_release_bus(slave);
>   
>   	return 0;
> diff --git a/include/spi.h b/include/spi.h
> index c33acd9eac..0c5f4c1739 100644
> --- a/include/spi.h
> +++ b/include/spi.h
> @@ -42,6 +42,8 @@
>   #define SPI_3BYTE_MODE 0x0
>   #define SPI_4BYTE_MODE 0x1
>   
> +#define SF_DUALIO_FLASH        0x1
> +
>   /* SPI transfer flags */
>   #define SPI_XFER_STRIPE	(1 << 6)
>   #define SPI_XFER_MASK	(3 << 8)
> @@ -172,6 +174,8 @@ struct spi_slave {
>   #define SPI_XFER_U_PAGE		BIT(4)
>   #define SPI_XFER_STACKED	BIT(5)
>   
> +	u8 dio;
> +	u8 dummy_bytes;

What is the purpose of this variables?

>   	u32 bytemode;
>   
>   	/*


More information about the U-Boot mailing list