[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(®s->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(®s->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(®s->ctrlr0,
> + TMOD_MASK << TMOD_SHIFT,
> + TMOD_TR << TMOD_SHIFT);
>
> return ret;
> }
>
More information about the U-Boot
mailing list