Message ID | 20240304-rk3588-saradc-v3-1-7424e2ed5d3b@theobroma-systems.com |
---|---|
State | Accepted |
Delegated to: | Kever Yang |
Headers | show |
Series | rockchip: add support for SARADCv2 and RK806 PMIC and regulators | expand |
On 2024/3/4 19:29, Quentin Schulz wrote: > From: Quentin Schulz <quentin.schulz@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@0leil.net> > Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com> Reviewed-by: Kever Yang <kever.yang@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; > } >
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; }