On Tue, Dec 17, 2013 at 4:17 AM, Stephen Warren <swar...@wwwdotorg.org> wrote: > From: Yen Lin <ye...@nvidia.com> > > The RDY bit indicates that a transfer is complete. This needs to be > cleared by SW before every single HW transaction, rather than only > at the start of each SW transaction (those being made up of n HW > transactions). > > It seems that earlier HW may have cleared this bit autonomously when > starting a new transfer, and hence this code was not needed in practice. > However, this is generally a good idea in all cases. In Tegra124, the > HW behaviour appears to have changed, and SW must explicitly clear this > bit. Otherwise, SW will believe that transfers have completed when they > have not, and may e.g. read stale data from the RX FIFO. > > Signed-off-by: Yen Lin <ye...@nvidia.com> > [swarren, rewrote commit description, unified duplicate RDY clearing code > and moved it right before the start of the HW transaction, unconditionally > exit loop after reading RX data, rather than checking if TX FIFO is empty, > since it is guaranteed to be] > Signed-off-by: Stephen Warren <swar...@nvidia.com> > --- > drivers/spi/tegra1x4_spi.c | 21 ++++++++------------- File not there in master -- please check.
> 1 file changed, 8 insertions(+), 13 deletions(-) > > diff --git a/drivers/spi/tegra1x4_spi.c b/drivers/spi/tegra1x4_spi.c > index 2742443e184c..a0c6537e8f5c 100644 > --- a/drivers/spi/tegra1x4_spi.c > +++ b/drivers/spi/tegra1x4_spi.c > @@ -275,9 +275,6 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned > int bitlen, > reg = readl(®s->fifo_status); > writel(reg, ®s->fifo_status); > > - /* clear ready bit */ > - setbits_le32(®s->xfer_status, SPI_XFER_STS_RDY); > - > clrsetbits_le32(®s->command1, SPI_CMD1_CS_SW_VAL, > SPI_CMD1_RX_EN | SPI_CMD1_TX_EN | SPI_CMD1_LSBY_FE | > (slave->cs << SPI_CMD1_CS_SEL_SHIFT)); > @@ -291,7 +288,6 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned > int bitlen, > /* handle data in 32-bit chunks */ > while (num_bytes > 0) { > int bytes; > - int is_read = 0; > int tm, i; > > tmpdout = 0; > @@ -305,6 +301,9 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned > int bitlen, > > num_bytes -= bytes; > > + /* clear ready bit */ > + setbits_le32(®s->xfer_status, SPI_XFER_STS_RDY); > + > clrsetbits_le32(®s->command1, > SPI_CMD1_BIT_LEN_MASK << > SPI_CMD1_BIT_LEN_SHIFT, > (bytes * 8 - 1) << SPI_CMD1_BIT_LEN_SHIFT); > @@ -315,20 +314,14 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned > int bitlen, > * Wait for SPI transmit FIFO to empty, or to time out. > * The RX FIFO status will be read and cleared last > */ > - for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) { > + for (tm = 0; tm < SPI_TIMEOUT; ++tm) { > u32 fifo_status, xfer_status; > > - fifo_status = readl(®s->fifo_status); > - > - /* We can exit when we've had both RX and TX activity > */ > - if (is_read && > - (fifo_status & SPI_FIFO_STS_TX_FIFO_EMPTY)) > - break; > - > xfer_status = readl(®s->xfer_status); > if (!(xfer_status & SPI_XFER_STS_RDY)) > continue; > > + fifo_status = readl(®s->fifo_status); > if (fifo_status & SPI_FIFO_STS_ERR) { > debug("%s: got a fifo error: ", __func__); > if (fifo_status & SPI_FIFO_STS_TX_FIFO_OVF) > @@ -353,7 +346,6 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned > int bitlen, > > if (!(fifo_status & SPI_FIFO_STS_RX_FIFO_EMPTY)) { > tmpdin = readl(®s->rx_fifo); > - is_read = 1; > > /* swap bytes read in */ > if (din != NULL) { > @@ -363,6 +355,9 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned > int bitlen, > } > din += bytes; > } > + > + /* We can exit when we've had both RX and TX > */ > + break; > } > } > > -- > 1.8.1.5 > -- Thanks, Jagan. -------- Jagannadha Sutradharudu Teki, E: jagannadh.t...@gmail.com, P: +91-9676773388 Engineer - System Software Hacker U-boot - SPI Custodian and Zynq APSOC Ln: http://www.linkedin.com/in/jaganteki _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot