Hello Paulraj, On 13/05/2010, at 17:10, Paulraj, Sandeep wrote: >> 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.
Sure, it was tested on a LogicPD Zoomâ„¢ OMAP-L138 eXperimenter Kit (da850_omapl138_evm_config). -- Delio >> 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