public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/2] Improve Raspberry Pi mmc writes
       [not found] <b45d36cb8f3ff07a9de93a9a0acc48c017410b0c>
@ 2017-04-02  8:24 ` Alex Deymo
  2017-04-02  8:24   ` [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up " Alex Deymo
  0 siblings, 1 reply; 5+ messages in thread
From: Alex Deymo @ 2017-04-02  8:24 UTC (permalink / raw)
  To: u-boot

When experimenting with fastboot from U-Boot on the Raspberry Pi 3 we
found that the writes to the sdcard are much more slow than when
accessing it from the userspace. These two patches speed up the write
and allow us to reliably write the sdcard from U-Boot.

Alex Deymo (1):
  mmc: sdhci: Wait for SDHCI_INT_DATA_END when transferring.

Jocelyn Bohr (1):
  mmc: bcm2835_sdhci: Speed up mmc writes.

 drivers/mmc/bcm2835_sdhci.c |  8 ++++++--
 drivers/mmc/sdhci.c         | 15 +++++++++++----
 2 files changed, 17 insertions(+), 6 deletions(-)

-- 
2.12.2.564.g063fe858b8-goog

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up mmc writes.
  2017-04-02  8:24 ` [U-Boot] [PATCH 0/2] Improve Raspberry Pi mmc writes Alex Deymo
@ 2017-04-02  8:24   ` Alex Deymo
  2017-04-02  8:24     ` [U-Boot] [PATCH 2/2] mmc: sdhci: Wait for SDHCI_INT_DATA_END when transferring Alex Deymo
  2017-04-06 22:42     ` [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up mmc writes Simon Glass
  0 siblings, 2 replies; 5+ messages in thread
From: Alex Deymo @ 2017-04-02  8:24 UTC (permalink / raw)
  To: u-boot

From: Jocelyn Bohr <bohr@google.com>

The linux kernel driver for this module does not use a delay when
writing to the SDHCI_BUFFER register. This patch mimics that behavior
in order to speed up the mmc writes on the Raspberry Pi.

Signed-off-by: Alex Deymo <deymo@google.com>
---
 drivers/mmc/bcm2835_sdhci.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index 29c2a85812..20079bce48 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -44,6 +44,7 @@
 
 /* 400KHz is max freq for card ID etc. Use that as min */
 #define MIN_FREQ 400000
+#define SDHCI_BUFFER 0x20
 
 struct bcm2835_sdhci_host {
 	struct sdhci_host host;
@@ -69,8 +70,11 @@ static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val,
 	 * (Which is just as well - otherwise we'd have to nobble the DMA engine
 	 * too)
 	 */
-	while (timer_get_us() - bcm_host->last_write < bcm_host->twoticks_delay)
-		;
+	if (reg != SDHCI_BUFFER) {
+		while (timer_get_us() - bcm_host->last_write <
+		       bcm_host->twoticks_delay)
+			;
+	}
 
 	writel(val, host->ioaddr + reg);
 	bcm_host->last_write = timer_get_us();
-- 
2.12.2.564.g063fe858b8-goog

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH 2/2] mmc: sdhci: Wait for SDHCI_INT_DATA_END when transferring.
  2017-04-02  8:24   ` [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up " Alex Deymo
@ 2017-04-02  8:24     ` Alex Deymo
  2017-04-06 22:42       ` Simon Glass
  2017-04-06 22:42     ` [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up mmc writes Simon Glass
  1 sibling, 1 reply; 5+ messages in thread
From: Alex Deymo @ 2017-04-02  8:24 UTC (permalink / raw)
  To: u-boot

sdhci_transfer_data() function transfers the blocks passed up to the
number of blocks defined in mmc_data, but returns immediately once all
the blocks are transferred, even if the loop exit condition is not met
(bit SDHCI_INT_DATA_END set in the STATUS word).

When doing multiple writes to mmc, returning right after the last block
is transferred can cause the write to fail when sending the
MMC_CMD_STOP_TRANSMISSION command right after the
MMC_CMD_WRITE_MULTIPLE_BLOCK command, leaving the mmc driver in an
unconsistent state until reboot. This error was observed in the rpi3
board.

This patch waits for the SDHCI_INT_DATA_END bit to be set even after
sending all the blocks.

Test: Reliably wrote 2GiB of data to mmc in a rpi3.

Signed-off-by: Alex Deymo <deymo@google.com>
---
 drivers/mmc/sdhci.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index c94d58db65..b745977b3f 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -72,6 +72,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
 				unsigned int start_addr)
 {
 	unsigned int stat, rdy, mask, timeout, block = 0;
+	bool transfer_done = false;
 #ifdef CONFIG_MMC_SDHCI_SDMA
 	unsigned char ctrl;
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
@@ -89,17 +90,23 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
 			       __func__, stat);
 			return -EIO;
 		}
-		if (stat & rdy) {
+		if (!transfer_done && (stat & rdy)) {
 			if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & mask))
 				continue;
 			sdhci_writel(host, rdy, SDHCI_INT_STATUS);
 			sdhci_transfer_pio(host, data);
 			data->dest += data->blocksize;
-			if (++block >= data->blocks)
-				break;
+			if (++block >= data->blocks) {
+				/* Keep looping until the SDHCI_INT_DATA_END is
+				 * cleared, even if we finished sending all the
+				 * blocks.
+				 */
+				transfer_done = true;
+				continue;
+			}
 		}
 #ifdef CONFIG_MMC_SDHCI_SDMA
-		if (stat & SDHCI_INT_DMA_END) {
+		if (!transfer_done && (stat & SDHCI_INT_DMA_END)) {
 			sdhci_writel(host, SDHCI_INT_DMA_END, SDHCI_INT_STATUS);
 			start_addr &= ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1);
 			start_addr += SDHCI_DEFAULT_BOUNDARY_SIZE;
-- 
2.12.2.564.g063fe858b8-goog

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up mmc writes.
  2017-04-02  8:24   ` [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up " Alex Deymo
  2017-04-02  8:24     ` [U-Boot] [PATCH 2/2] mmc: sdhci: Wait for SDHCI_INT_DATA_END when transferring Alex Deymo
@ 2017-04-06 22:42     ` Simon Glass
  1 sibling, 0 replies; 5+ messages in thread
From: Simon Glass @ 2017-04-06 22:42 UTC (permalink / raw)
  To: u-boot

On 2 April 2017 at 02:24, Alex Deymo <deymo@google.com> wrote:
> From: Jocelyn Bohr <bohr@google.com>
>
> The linux kernel driver for this module does not use a delay when
> writing to the SDHCI_BUFFER register. This patch mimics that behavior
> in order to speed up the mmc writes on the Raspberry Pi.
>
> Signed-off-by: Alex Deymo <deymo@google.com>
> ---
>  drivers/mmc/bcm2835_sdhci.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH 2/2] mmc: sdhci: Wait for SDHCI_INT_DATA_END when transferring.
  2017-04-02  8:24     ` [U-Boot] [PATCH 2/2] mmc: sdhci: Wait for SDHCI_INT_DATA_END when transferring Alex Deymo
@ 2017-04-06 22:42       ` Simon Glass
  0 siblings, 0 replies; 5+ messages in thread
From: Simon Glass @ 2017-04-06 22:42 UTC (permalink / raw)
  To: u-boot

On 2 April 2017 at 02:24, Alex Deymo <deymo@google.com> wrote:
> sdhci_transfer_data() function transfers the blocks passed up to the
> number of blocks defined in mmc_data, but returns immediately once all
> the blocks are transferred, even if the loop exit condition is not met
> (bit SDHCI_INT_DATA_END set in the STATUS word).
>
> When doing multiple writes to mmc, returning right after the last block
> is transferred can cause the write to fail when sending the
> MMC_CMD_STOP_TRANSMISSION command right after the
> MMC_CMD_WRITE_MULTIPLE_BLOCK command, leaving the mmc driver in an
> unconsistent state until reboot. This error was observed in the rpi3
> board.
>
> This patch waits for the SDHCI_INT_DATA_END bit to be set even after
> sending all the blocks.
>
> Test: Reliably wrote 2GiB of data to mmc in a rpi3.
>
> Signed-off-by: Alex Deymo <deymo@google.com>
> ---
>  drivers/mmc/sdhci.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-04-06 22:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <b45d36cb8f3ff07a9de93a9a0acc48c017410b0c>
2017-04-02  8:24 ` [U-Boot] [PATCH 0/2] Improve Raspberry Pi mmc writes Alex Deymo
2017-04-02  8:24   ` [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up " Alex Deymo
2017-04-02  8:24     ` [U-Boot] [PATCH 2/2] mmc: sdhci: Wait for SDHCI_INT_DATA_END when transferring Alex Deymo
2017-04-06 22:42       ` Simon Glass
2017-04-06 22:42     ` [U-Boot] [PATCH 1/2] mmc: bcm2835_sdhci: Speed up mmc writes Simon Glass

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox