mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 06:31:31 +00:00
spi: sh_qspi: Make use of the 32byte FIFO
The QSPI controller on RCar Gen2 has 32byte FIFO. Instead of doing the SPI transmission 1 byte at time, if there is a 32byte chunk of data to be transferred, fill the FIFO completely and then transfer the data to/from the FIFO. This increases the SPI NOR access speed significantly. Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com> Cc: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
This commit is contained in:
parent
9573db654d
commit
ea5512eb09
1 changed files with 24 additions and 10 deletions
|
@ -36,6 +36,8 @@
|
||||||
SPCMD_BRDV0
|
SPCMD_BRDV0
|
||||||
#define SPBFCR_TXRST BIT(7)
|
#define SPBFCR_TXRST BIT(7)
|
||||||
#define SPBFCR_RXRST BIT(6)
|
#define SPBFCR_RXRST BIT(6)
|
||||||
|
#define SPBFCR_TXTRG 0x30
|
||||||
|
#define SPBFCR_RXTRG 0x07
|
||||||
|
|
||||||
/* SH QSPI register set */
|
/* SH QSPI register set */
|
||||||
struct sh_qspi_regs {
|
struct sh_qspi_regs {
|
||||||
|
@ -201,8 +203,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
|
||||||
void *din, unsigned long flags)
|
void *din, unsigned long flags)
|
||||||
{
|
{
|
||||||
struct sh_qspi_slave *ss = to_sh_qspi(slave);
|
struct sh_qspi_slave *ss = to_sh_qspi(slave);
|
||||||
u32 nbyte;
|
u32 nbyte, chunk;
|
||||||
int ret = 0;
|
int i, ret = 0;
|
||||||
u8 dtdata = 0, drdata;
|
u8 dtdata = 0, drdata;
|
||||||
u8 *tdata = &dtdata, *rdata = &drdata;
|
u8 *tdata = &dtdata, *rdata = &drdata;
|
||||||
u32 *spbmul0 = &ss->regs->spbmul0;
|
u32 *spbmul0 = &ss->regs->spbmul0;
|
||||||
|
@ -237,26 +239,38 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
|
||||||
rdata = din;
|
rdata = din;
|
||||||
|
|
||||||
while (nbyte > 0) {
|
while (nbyte > 0) {
|
||||||
|
/*
|
||||||
|
* Check if there is 32 Byte chunk and if there is, transfer
|
||||||
|
* it in one burst, otherwise transfer on byte-by-byte basis.
|
||||||
|
*/
|
||||||
|
chunk = (nbyte >= 32) ? 32 : 1;
|
||||||
|
|
||||||
|
clrsetbits_8(&ss->regs->spbfcr, SPBFCR_TXTRG | SPBFCR_RXTRG,
|
||||||
|
chunk == 32 ? SPBFCR_TXTRG | SPBFCR_RXTRG : 0);
|
||||||
|
|
||||||
ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPTEF,
|
ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPTEF,
|
||||||
true, 1000, true);
|
true, 1000, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
writeb(*tdata, (u8 *)(&ss->regs->spdr));
|
for (i = 0; i < chunk; i++) {
|
||||||
|
writeb(*tdata, &ss->regs->spdr);
|
||||||
|
if (dout != NULL)
|
||||||
|
tdata++;
|
||||||
|
}
|
||||||
|
|
||||||
ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPRFF,
|
ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPRFF,
|
||||||
true, 1000, true);
|
true, 1000, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
*rdata = readb((u8 *)(&ss->regs->spdr));
|
for (i = 0; i < chunk; i++) {
|
||||||
|
*rdata = readb(&ss->regs->spdr);
|
||||||
|
if (din != NULL)
|
||||||
|
rdata++;
|
||||||
|
}
|
||||||
|
|
||||||
if (dout != NULL)
|
nbyte -= chunk;
|
||||||
tdata++;
|
|
||||||
if (din != NULL)
|
|
||||||
rdata++;
|
|
||||||
|
|
||||||
nbyte--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & SPI_XFER_END)
|
if (flags & SPI_XFER_END)
|
||||||
|
|
Loading…
Add table
Reference in a new issue