Message ID | 1394699364-5669-2-git-send-email-cm-hiep@jinso.co.jp (mailing list archive) |
---|---|
State | RFC |
Headers | show |
On Thu, Mar 13, 2014 at 9:29 AM, Cao Minh Hiep <cm-hiep@jinso.co.jp> wrote: > In order to transmit and receive data when have 32 bytes of data that > ready has prepared on Transmit/Receive Buffer to transmit or receive. > Instead transmits/receives a byte data using Transmit/Receive Buffer > Data Triggering Number will improve the speed of transfer data. Thanks for your patch, this looks like a valuable improvement! Unfortunately your patch doesn't apply against spi/for-next anymore, as the driver has changed a lot lately, due to the addition of RZ/A1H and Quad/Dual support. > +static void qspi_update(const struct rspi_data *rspi, u8 mask, u8 val, u8 reg) > +{ > + u8 data; > + > + data = rspi_read8(rspi, reg); > + data &= ~mask; > + data |= (val & mask); I think this "& mask" is superfluous. > + rspi_write8(rspi, data, reg); > +} > +static int qspi_set_send_trigger(struct rspi_data *rspi, int remain) > +{ > + int n; > + > + n = min(remain, QSPI_BUFFER_SIZE); > + > + if (remain >= QSPI_BUFFER_SIZE) { > + /* sets triggering number to 32 bytes */ "0 bytes"? (comment copied from qspi_set_receive_trigger()) > + qspi_update(rspi, SPBFCR_TXTRG_MASK, > + SPBFCR_TXTRG_0B, QSPI_SPBFCR); > + } else { > + /* sets triggering number to 1 byte */ "31 bytes"? > + qspi_update(rspi, SPBFCR_TXTRG_MASK, > + SPBFCR_TXTRG_31B, QSPI_SPBFCR); > + } > @@ -389,9 +443,10 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, > { > int remain = t->len; > const u8 *data = t->tx_buf; > + int i, n; > > rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR); > - rspi_write8(rspi, 0x00, QSPI_SPBFCR); > + rspi_write8(rspi, DUMMY_DATA, QSPI_SPBFCR); I think this should stay "0x00", as it's not dummy data written to the transmit data register. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Hiep > In order to transmit and receive data when have 32 bytes of data that > ready has prepared on Transmit/Receive Buffer to transmit or receive. > Instead transmits/receives a byte data using Transmit/Receive Buffer > Data Triggering Number will improve the speed of transfer data. > > Signed-off-by: Hiep Cao Minh <cm-hiep@jinso.co.jp> > --- (snip) > +static int qspi_set_send_trigger(struct rspi_data *rspi, int remain) > +{ > + int n; > + > + n = min(remain, QSPI_BUFFER_SIZE); > + > + if (remain >= QSPI_BUFFER_SIZE) { > + /* sets triggering number to 32 bytes */ > + qspi_update(rspi, SPBFCR_TXTRG_MASK, > + SPBFCR_TXTRG_0B, QSPI_SPBFCR); > + } else { > + /* sets triggering number to 1 byte */ > + qspi_update(rspi, SPBFCR_TXTRG_MASK, > + SPBFCR_TXTRG_31B, QSPI_SPBFCR); > + } > + > + return n; > +} (snip) > + n = qspi_set_send_trigger(rspi, remain); > + if (n >= QSPI_BUFFER_SIZE) { > + for (i = 0; i < n; i++) > + rspi_write8(rspi, *data++, RSPI_SPDR); > + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, > + SPCR_SPRIE) < 0) { > + dev_err(&rspi->master->dev, > + "%s: receive timeout\n", __func__); > + return -ETIMEDOUT; > + } > + for (i = 0; i < n; i++) > + rspi_read8(rspi, RSPI_SPDR); > + } else { > + for (i = 0; i < n; i++) { > + if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, > + SPCR_SPTIE) < 0) { > + dev_err(&rspi->master->dev, > + "%s: tx empty timeout\n", __func__); > + return -ETIMEDOUT; > + } > + rspi_write8(rspi, *data++, RSPI_SPDR); > + > + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, > + SPCR_SPRIE) < 0) { > + dev_err(&rspi->master->dev, > + "%s: receive timeout\n", __func__); > + return -ETIMEDOUT; > + } > + rspi_read8(rspi, RSPI_SPDR); > + } I guess, this "qspi_set_send_trigger()" is mode "settings", and, "transfer" is done here. I think "setting" and "tranfer" in 1 function is readable. -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 03/13/2014 06:23 PM, Geert Uytterhoeven wrote: > On Thu, Mar 13, 2014 at 9:29 AM, Cao Minh Hiep <cm-hiep@jinso.co.jp> wrote: >> In order to transmit and receive data when have 32 bytes of data that >> ready has prepared on Transmit/Receive Buffer to transmit or receive. >> Instead transmits/receives a byte data using Transmit/Receive Buffer >> Data Triggering Number will improve the speed of transfer data. > Thanks for your patch, this looks like a valuable improvement! > > Unfortunately your patch doesn't apply against spi/for-next anymore, as > the driver has changed a lot lately, due to the addition of RZ/A1H and > Quad/Dual support. > Thanks, Do you mean this patch did not need for next and I don't mind about it? >> +static void qspi_update(const struct rspi_data *rspi, u8 mask, u8 val, u8 reg) >> +{ >> + u8 data; >> + >> + data = rspi_read8(rspi, reg); >> + data &= ~mask; >> + data |= (val & mask); > I think this "& mask" is superfluous. thanks, I modified it. >> + rspi_write8(rspi, data, reg); >> +} >> +static int qspi_set_send_trigger(struct rspi_data *rspi, int remain) >> +{ >> + int n; >> + >> + n = min(remain, QSPI_BUFFER_SIZE); >> + >> + if (remain >= QSPI_BUFFER_SIZE) { >> + /* sets triggering number to 32 bytes */ > "0 bytes"? (comment copied from qspi_set_receive_trigger()) > >> + qspi_update(rspi, SPBFCR_TXTRG_MASK, >> + SPBFCR_TXTRG_0B, QSPI_SPBFCR); >> + } else { >> + /* sets triggering number to 1 byte */ > "31 bytes"? thanks, >> + qspi_update(rspi, SPBFCR_TXTRG_MASK, >> + SPBFCR_TXTRG_31B, QSPI_SPBFCR); >> + } >> @@ -389,9 +443,10 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, >> { >> int remain = t->len; >> const u8 *data = t->tx_buf; >> + int i, n; >> >> rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR); >> - rspi_write8(rspi, 0x00, QSPI_SPBFCR); >> + rspi_write8(rspi, DUMMY_DATA, QSPI_SPBFCR); > I think this should stay "0x00", as it's not dummy data written to the > transmit data register. Thanks, > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like that. > -- Linus Torvalds > > -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Morimoto On 03/13/2014 06:27 PM, Kuninori Morimoto wrote: > Hi Hiep > >> In order to transmit and receive data when have 32 bytes of data that >> ready has prepared on Transmit/Receive Buffer to transmit or receive. >> Instead transmits/receives a byte data using Transmit/Receive Buffer >> Data Triggering Number will improve the speed of transfer data. >> >> Signed-off-by: Hiep Cao Minh <cm-hiep@jinso.co.jp> >> --- > (snip) >> +static int qspi_set_send_trigger(struct rspi_data *rspi, int remain) >> +{ >> + int n; >> + >> + n = min(remain, QSPI_BUFFER_SIZE); >> + >> + if (remain >= QSPI_BUFFER_SIZE) { >> + /* sets triggering number to 32 bytes */ >> + qspi_update(rspi, SPBFCR_TXTRG_MASK, >> + SPBFCR_TXTRG_0B, QSPI_SPBFCR); >> + } else { >> + /* sets triggering number to 1 byte */ >> + qspi_update(rspi, SPBFCR_TXTRG_MASK, >> + SPBFCR_TXTRG_31B, QSPI_SPBFCR); >> + } >> + >> + return n; >> +} > (snip) >> + n = qspi_set_send_trigger(rspi, remain); >> + if (n >= QSPI_BUFFER_SIZE) { >> + for (i = 0; i < n; i++) >> + rspi_write8(rspi, *data++, RSPI_SPDR); >> + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, >> + SPCR_SPRIE) < 0) { >> + dev_err(&rspi->master->dev, >> + "%s: receive timeout\n", __func__); >> + return -ETIMEDOUT; >> + } >> + for (i = 0; i < n; i++) >> + rspi_read8(rspi, RSPI_SPDR); >> + } else { >> + for (i = 0; i < n; i++) { >> + if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, >> + SPCR_SPTIE) < 0) { >> + dev_err(&rspi->master->dev, >> + "%s: tx empty timeout\n", __func__); >> + return -ETIMEDOUT; >> + } >> + rspi_write8(rspi, *data++, RSPI_SPDR); >> + >> + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, >> + SPCR_SPRIE) < 0) { >> + dev_err(&rspi->master->dev, >> + "%s: receive timeout\n", __func__); >> + return -ETIMEDOUT; >> + } >> + rspi_read8(rspi, RSPI_SPDR); >> + } > I guess, this "qspi_set_send_trigger()" is mode "settings", > and, "transfer" is done here. > > I think "setting" and "tranfer" in 1 function is readable. > Thanks for your comments, I will do so. -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Hiep, On Mon, Mar 17, 2014 at 2:11 AM, ?????????? <cm-hiep@jinso.co.jp> wrote: > On 03/13/2014 06:23 PM, Geert Uytterhoeven wrote: >> On Thu, Mar 13, 2014 at 9:29 AM, Cao Minh Hiep <cm-hiep@jinso.co.jp> >> wrote: >>> In order to transmit and receive data when have 32 bytes of data that >>> ready has prepared on Transmit/Receive Buffer to transmit or receive. >>> Instead transmits/receives a byte data using Transmit/Receive Buffer >>> Data Triggering Number will improve the speed of transfer data. >> >> Thanks for your patch, this looks like a valuable improvement! >> >> Unfortunately your patch doesn't apply against spi/for-next anymore, as >> the driver has changed a lot lately, due to the addition of RZ/A1H and >> Quad/Dual support. >> > Thanks, Do you mean this patch did not need for next and I don't mind about > it? It means you will have to rework your patch to apply on top of https://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/tree/drivers/spi?h=for-next before the SPI maintainer can accept it. Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Geert On 03/17/2014 04:54 PM, Geert Uytterhoeven wrote: > Hi Hiep, > > On Mon, Mar 17, 2014 at 2:11 AM, ?????????? <cm-hiep@jinso.co.jp> wrote: >> On 03/13/2014 06:23 PM, Geert Uytterhoeven wrote: >>> On Thu, Mar 13, 2014 at 9:29 AM, Cao Minh Hiep <cm-hiep@jinso.co.jp> >>> wrote: >>>> In order to transmit and receive data when have 32 bytes of data that >>>> ready has prepared on Transmit/Receive Buffer to transmit or receive. >>>> Instead transmits/receives a byte data using Transmit/Receive Buffer >>>> Data Triggering Number will improve the speed of transfer data. >>> Thanks for your patch, this looks like a valuable improvement! >>> >>> Unfortunately your patch doesn't apply against spi/for-next anymore, as >>> the driver has changed a lot lately, due to the addition of RZ/A1H and >>> Quad/Dual support. >>> >> Thanks, Do you mean this patch did not need for next and I don't mind about >> it? > It means you will have to rework your patch to apply on top of > https://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/tree/drivers/spi?h=for-next > before the SPI maintainer can accept it. Thanks, I understood, I will rework my patch and report to your later. Cao Minh Hiep. -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Hiep, On Mon, Mar 17, 2014 at 1:01 PM, ?????????? <cm-hiep@jinso.co.jp> wrote: > On 03/17/2014 04:54 PM, Geert Uytterhoeven wrote: >> On Mon, Mar 17, 2014 at 2:11 AM, ?????????? <cm-hiep@jinso.co.jp> wrote: >>> On 03/13/2014 06:23 PM, Geert Uytterhoeven wrote: >>>> On Thu, Mar 13, 2014 at 9:29 AM, Cao Minh Hiep <cm-hiep@jinso.co.jp> >>>> wrote: >>>>> In order to transmit and receive data when have 32 bytes of data that >>>>> ready has prepared on Transmit/Receive Buffer to transmit or receive. >>>>> Instead transmits/receives a byte data using Transmit/Receive Buffer >>>>> Data Triggering Number will improve the speed of transfer data. >>>> >>>> Thanks for your patch, this looks like a valuable improvement! >>>> >>>> Unfortunately your patch doesn't apply against spi/for-next anymore, as >>>> the driver has changed a lot lately, due to the addition of RZ/A1H and >>>> Quad/Dual support. >>>> >>> Thanks, Do you mean this patch did not need for next and I don't mind >>> about >>> it? >> >> It means you will have to rework your patch to apply on top of >> >> https://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/tree/drivers/spi?h=for-next >> before the SPI maintainer can accept it. > > Thanks, I understood, I will rework my patch and report to your later. I gave your patch a try on a v3.14-rc5 kernel on r8a7791/Koelsch, and it increased Single SPI read transfer speed from ca. 1 Mbps to 11 Mbps. So I'm looking forward to an updated version. Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Mar 17, 2014 at 08:48:43PM +0100, Geert Uytterhoeven wrote: > I gave your patch a try on a v3.14-rc5 kernel on r8a7791/Koelsch, > and it increased Single SPI read transfer speed from ca. 1 Mbps to 11 Mbps. > So I'm looking forward to an updated version. Nice!
Hi Geert On 03/18/2014 04:48 AM, Geert Uytterhoeven wrote: > Hi Hiep, > > On Mon, Mar 17, 2014 at 1:01 PM, ?????????? <cm-hiep@jinso.co.jp> wrote: >> On 03/17/2014 04:54 PM, Geert Uytterhoeven wrote: >>> On Mon, Mar 17, 2014 at 2:11 AM, ?????????? <cm-hiep@jinso.co.jp> wrote: >>>> On 03/13/2014 06:23 PM, Geert Uytterhoeven wrote: >>>>> On Thu, Mar 13, 2014 at 9:29 AM, Cao Minh Hiep <cm-hiep@jinso.co.jp> >>>>> wrote: >>>>>> In order to transmit and receive data when have 32 bytes of data that >>>>>> ready has prepared on Transmit/Receive Buffer to transmit or receive. >>>>>> Instead transmits/receives a byte data using Transmit/Receive Buffer >>>>>> Data Triggering Number will improve the speed of transfer data. >>>>> Thanks for your patch, this looks like a valuable improvement! >>>>> >>>>> Unfortunately your patch doesn't apply against spi/for-next anymore, as >>>>> the driver has changed a lot lately, due to the addition of RZ/A1H and >>>>> Quad/Dual support. >>>>> >>>> Thanks, Do you mean this patch did not need for next and I don't mind >>>> about >>>> it? >>> It means you will have to rework your patch to apply on top of >>> >>> https://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/tree/drivers/spi?h=for-next >>> before the SPI maintainer can accept it. >> Thanks, I understood, I will rework my patch and report to your later. > I gave your patch a try on a v3.14-rc5 kernel on r8a7791/Koelsch, > and it increased Single SPI read transfer speed from ca. 1 Mbps to 11 Mbps. > So I'm looking forward to an updated version. Thanks, I am modifying my patch and will send it to you as soon as possible. Hiep -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Geert, Hiep > > +static void qspi_update(const struct rspi_data *rspi, u8 mask, u8 val, u8 reg) > > +{ > > + u8 data; > > + > > + data = rspi_read8(rspi, reg); > > + data &= ~mask; > > + data |= (val & mask); > > I think this "& mask" is superfluous. This "& mask" protects data from un-anticipative overwrite IMO. Other driver is using same style. ex) snd_soc_update_bits() -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 28987d9..772a942 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -174,6 +174,12 @@ #define SPBFCR_RXRST 0x40 /* Receive Buffer Data Reset (qspi only) */ #define SPBFCR_TXTRG_MASK 0x30 /* Transmit Buffer Data Triggering Number */ #define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */ +#define SPBFCR_TXTRG_31B 0x00 /* QSPI only */ +#define SPBFCR_TXTRG_0B 0x30 /* QSPI only */ +#define SPBFCR_RXTRG_1B 0x00 /* QSPI only */ +#define SPBFCR_RXTRG_32B 0x07 /* QSPI only */ + +#define QSPI_BUFFER_SIZE 32 #define DUMMY_DATA 0x00 @@ -224,6 +230,16 @@ static u16 rspi_read16(const struct rspi_data *rspi, u16 offset) return ioread16(rspi->addr + offset); } +static void qspi_update(const struct rspi_data *rspi, u8 mask, u8 val, u8 reg) +{ + u8 data; + + data = rspi_read8(rspi, reg); + data &= ~mask; + data |= (val & mask); + rspi_write8(rspi, data, reg); +} + /* optional functions */ struct spi_ops { int (*set_config_register)(const struct rspi_data *rspi, @@ -358,6 +374,44 @@ static void rspi_negate_ssl(const struct rspi_data *rspi) rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR); } +static int qspi_set_send_trigger(struct rspi_data *rspi, int remain) +{ + int n; + + n = min(remain, QSPI_BUFFER_SIZE); + + if (remain >= QSPI_BUFFER_SIZE) { + /* sets triggering number to 32 bytes */ + qspi_update(rspi, SPBFCR_TXTRG_MASK, + SPBFCR_TXTRG_0B, QSPI_SPBFCR); + } else { + /* sets triggering number to 1 byte */ + qspi_update(rspi, SPBFCR_TXTRG_MASK, + SPBFCR_TXTRG_31B, QSPI_SPBFCR); + } + + return n; +} + +static int qspi_set_receive_trigger(struct rspi_data *rspi, int remain) +{ + int n; + + n = min(remain, QSPI_BUFFER_SIZE); + + if (remain >= QSPI_BUFFER_SIZE) { + /* sets triggering number to 32 bytes */ + qspi_update(rspi, SPBFCR_RXTRG_MASK, + SPBFCR_RXTRG_32B, QSPI_SPBFCR); + } else { + /* sets triggering number to 1 byte */ + qspi_update(rspi, SPBFCR_RXTRG_MASK, + SPBFCR_RXTRG_1B, QSPI_SPBFCR); + } + + return n; +} + static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, struct spi_transfer *t) { @@ -389,9 +443,10 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, { int remain = t->len; const u8 *data = t->tx_buf; + int i, n; rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR); - rspi_write8(rspi, 0x00, QSPI_SPBFCR); + rspi_write8(rspi, DUMMY_DATA, QSPI_SPBFCR); while (remain > 0) { @@ -400,16 +455,38 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, "%s: tx empty timeout\n", __func__); return -ETIMEDOUT; } - rspi_write8(rspi, *data++, RSPI_SPDR); - - if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { - dev_err(&rspi->master->dev, - "%s: receive timeout\n", __func__); - return -ETIMEDOUT; + n = qspi_set_send_trigger(rspi, remain); + if (n >= QSPI_BUFFER_SIZE) { + for (i = 0; i < n; i++) + rspi_write8(rspi, *data++, RSPI_SPDR); + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, + SPCR_SPRIE) < 0) { + dev_err(&rspi->master->dev, + "%s: receive timeout\n", __func__); + return -ETIMEDOUT; + } + for (i = 0; i < n; i++) + rspi_read8(rspi, RSPI_SPDR); + } else { + for (i = 0; i < n; i++) { + if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, + SPCR_SPTIE) < 0) { + dev_err(&rspi->master->dev, + "%s: tx empty timeout\n", __func__); + return -ETIMEDOUT; + } + rspi_write8(rspi, *data++, RSPI_SPDR); + + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, + SPCR_SPRIE) < 0) { + dev_err(&rspi->master->dev, + "%s: receive timeout\n", __func__); + return -ETIMEDOUT; + } + rspi_read8(rspi, RSPI_SPDR); + } } - rspi_read8(rspi, RSPI_SPDR); - - remain--; + remain -= n; } /* Waiting for the last transmission */ @@ -603,6 +680,7 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, { int remain = t->len; u8 *data; + int i, n; qspi_receive_init(rspi); @@ -614,17 +692,43 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, "%s: tx empty timeout\n", __func__); return -ETIMEDOUT; } - /* dummy write for generate clock */ - rspi_write8(rspi, DUMMY_DATA, RSPI_SPDR); - - if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { - dev_err(&rspi->master->dev, - "%s: receive timeout\n", __func__); - return -ETIMEDOUT; + n = qspi_set_receive_trigger(rspi, remain); + if (n >= QSPI_BUFFER_SIZE) { + /* dummy write for generate clock */ + for (i = 0; i < n; i++) + rspi_write8(rspi, DUMMY_DATA, RSPI_SPDR); + + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, + SPCR_SPRIE) < 0) { + dev_err(&rspi->master->dev, + "%s: receive timeout\n", __func__); + return -ETIMEDOUT; + } + /* SPDR allows 8, 16 or 32-bit access */ + for (i = 0; i < n; i++) + *data++ = rspi_read8(rspi, RSPI_SPDR); + } else { + for (i = 0; i < n; i++) { + if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, + SPCR_SPTIE) < 0) { + dev_err(&rspi->master->dev, + "%s: tx empty timeout\n", __func__); + return -ETIMEDOUT; + } + /* dummy write for generate clock */ + rspi_write8(rspi, DUMMY_DATA, RSPI_SPDR); + + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, + SPCR_SPRIE) < 0) { + dev_err(&rspi->master->dev, + "%s: receive timeout\n", __func__); + return -ETIMEDOUT; + } + /* SPDR allows 8, 16 or 32-bit access */ + *data++ = rspi_read8(rspi, RSPI_SPDR); + } } - /* SPDR allows 8, 16 or 32-bit access */ - *data++ = rspi_read8(rspi, RSPI_SPDR); - remain--; + remain -= n; } return 0;