> 
> 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

Reply via email to