[PATCH v3 01/16] rockchip: spi: rk_spi: do not write bytes when in read-only mode

Kever Yang kever.yang at rock-chips.com
Wed Mar 13 11:30:03 CET 2024


On 2024/3/4 19:29, Quentin Schulz wrote:
> From: Quentin Schulz <quentin.schulz at theobroma-systems.com>
>
> The read-only mode is currently supported but only for 16b-aligned
> buffers. For unaligned buffers, the last byte will be read in RW mode
> right now, which isn't what is desired. Instead, let's put the
> controller back into RO mode for that last byte and skip any write in
> the xfer loop.
>
> This is required for 3-wire SPI mode where PICO/POCI lanes are shorted
> on HW level. This incidentally the recommended design for RK806 PMIC for
> RK3588 products.
>
> Cc: Quentin Schulz <foss+uboot at 0leil.net>
> Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>

Thanks,
- Kever
> ---
>   drivers/spi/rk_spi.c | 20 +++++++++++++++++---
>   1 file changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
> index 7de943356ad..c8694fdff95 100644
> --- a/drivers/spi/rk_spi.c
> +++ b/drivers/spi/rk_spi.c
> @@ -453,8 +453,17 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
>   	 * case of read-only transfers by using the full 16bits of each
>   	 * FIFO element.
>   	 */
> -	if (!out)
> +	if (!out) {
>   		ret = rockchip_spi_16bit_reader(dev, &in, &len);
> +		/*
> +		 * If "in" isn't 16b-aligned, we need to send the last byte
> +		 * ourselves. We however need to have the controller in RO mode
> +		 * which differs from the default.
> +		 */
> +		clrsetbits_le32(&regs->ctrlr0,
> +				TMOD_MASK << TMOD_SHIFT,
> +				TMOD_RO << TMOD_SHIFT);
> +	}
>   
>   	/* This is the original 8bit reader/writer code */
>   	while (len > 0) {
> @@ -465,12 +474,13 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
>   		rkspi_enable_chip(regs, true);
>   
>   		toread = todo;
> -		towrite = todo;
> +		/* Only write if we have something to write */
> +		towrite = out ? todo : 0;
>   		while (toread || towrite) {
>   			u32 status = readl(&regs->sr);
>   
>   			if (towrite && !(status & SR_TF_FULL)) {
> -				writel(out ? *out++ : 0, regs->txdr);
> +				writel(*out++, regs->txdr);
>   				towrite--;
>   			}
>   			if (toread && !(status & SR_RF_EMPT)) {
> @@ -501,6 +511,10 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
>   		spi_cs_deactivate(dev, slave_plat->cs);
>   
>   	rkspi_enable_chip(regs, false);
> +	if (!out)
> +		clrsetbits_le32(&regs->ctrlr0,
> +				TMOD_MASK << TMOD_SHIFT,
> +				TMOD_TR << TMOD_SHIFT);
>   
>   	return ret;
>   }
>


More information about the U-Boot mailing list