> > Reduce the number of reads per byte transferred on the BUF register from 2 > to 1 and > take advantage of the TX buffer in the SPI module.
May I ask which chip device this was tested on. > > Signed-off-by: Delio Brignoli <dbrign...@audioscience.com> > --- > drivers/spi/davinci_spi.c | 67 +++++++++++++++++++++++----------------- > ---- > 1 files changed, 35 insertions(+), 32 deletions(-) > > diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c > index 60ba007..b4a74de 100644 > --- a/drivers/spi/davinci_spi.c > +++ b/drivers/spi/davinci_spi.c > @@ -131,6 +131,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int > bitlen, > { > struct davinci_spi_slave *ds = to_davinci_spi(slave); > unsigned int len, data1_reg_val = readl(&ds->regs->dat1); > + unsigned int i_cnt = 0, o_cnt = 0, buf_reg_val; > int ret, i; > const u8 *txp = dout; /* dout can be NULL for read operation */ > u8 *rxp = din; /* din can be NULL for write operation */ > @@ -159,41 +160,43 @@ int spi_xfer(struct spi_slave *slave, unsigned int > bitlen, > readl(&ds->regs->buf); > > /* keep writing and reading 1 byte until done */ > - for (i = 0; i < len; i++) { > - /* wait till TXFULL is asserted */ > - while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK); > - > - /* write the data */ > - data1_reg_val &= ~0xFFFF; > - if (txp) { > - data1_reg_val |= *txp; > - txp++; > + while((i_cnt < len) || (o_cnt < len)) { > + /* read RX buffer and flags */ > + buf_reg_val = readl(&ds->regs->buf); > + > + /* if data is available */ > + if ((i_cnt < len) && (buf_reg_val & SPIBUF_RXEMPTY_MASK) == 0) > { > + /* if there is no read buffer simply ignore the read > character */ > + if(rxp) { > + *rxp = buf_reg_val & 0xFF; > + rxp++; > + } > + /* increment read words count */ > + i_cnt++; > } > > - /* > - * Write to DAT1 is required to keep the serial transfer going. > - * We just terminate when we reach the end. > - */ > - if ((i == (len - 1)) && (flags & SPI_XFER_END)) { > - /* clear CS hold */ > - writel(data1_reg_val & > - ~(1 << SPIDAT1_CSHOLD_SHIFT), &ds->regs->dat1); > - } else { > - /* enable CS hold */ > - data1_reg_val |= ((1 << SPIDAT1_CSHOLD_SHIFT) | > + /* if the tx buffer is empty and there is still data to > transmit */ > + if ((o_cnt < len) && ((buf_reg_val & SPIBUF_TXFULL_MASK) == > 0)) { > + /* write the data */ > + data1_reg_val &= ~0xFFFF; > + if(txp) { > + data1_reg_val |= *txp; > + txp++; > + } > + /* write to DAT1 is required to keep the serial transfer > going */ > + /* we just terminate when we reach the end */ > + if((o_cnt == (len -1)) && (flags & SPI_XFER_END)) { > + /* clear CS hold */ > + writel(data1_reg_val & > + ~(1 << SPIDAT1_CSHOLD_SHIFT), &ds->regs- > >dat1); > + } else { > + /* enable CS hold and write TX register */ > + data1_reg_val |= ((1 << SPIDAT1_CSHOLD_SHIFT) | > (slave->cs << SPIDAT1_CSNR_SHIFT)); > - writel(data1_reg_val, &ds->regs->dat1); > - } > - > - /* read the data - wait for data availability */ > - while (readl(&ds->regs->buf) & SPIBUF_RXEMPTY_MASK); > - > - if (rxp) { > - *rxp = readl(&ds->regs->buf) & 0xFF; > - rxp++; > - } else { > - /* simply drop the read character */ > - readl(&ds->regs->buf); > + writel(data1_reg_val, &ds->regs->dat1); > + } > + /* increment written words count */ > + o_cnt++; > } > } > return 0; > -- > 1.6.3.3 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot