linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mvsdio: fix config failure with some high speed SDHC cards
@ 2009-05-27  2:35 Nicolas Pitre
  2009-05-27 20:26 ` Pierre Ossman
  0 siblings, 1 reply; 2+ messages in thread
From: Nicolas Pitre @ 2009-05-27  2:35 UTC (permalink / raw)
  To: Pierre Ossman; +Cc: lkml

    
Especially with Sandisk SDHC cards, the second SWITCH command was failing
with a timeout and the card was not recognized at all.  However if the
system was busy, or debugging was enabled, or a udelay(100) was inserted
before the second SWITCH command in the core code, then the timing was
so that the card started to work.

This appears to be a problem with the host hardware.  With some unusual
block sizes, the data FIFO status doesn't indicate a "empty" state right
away when the data transfer is done.  Queuing another data transfer in
that condition results in a transfer timeout.

The empty FIFO bit eventually get set by itself in less than 50 usecs
when it is not set right away. So let's just poll for that bit before
configuring the controller with a new data transfer.

Signed-off-by: Nicolas Pitre <nico@marvell.com>

diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index 9d3cfa9..b56d72f 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -64,6 +64,31 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
 	unsigned int tmout;
 	int tmout_index;
 
+	/*
+	 * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
+	 * register is sometimes not set before a while when some
+	 * "unusual" data block sizes are used (such as with the SWITCH
+	 * command), even despite the fact that the XFER_DONE interrupt
+	 * was raised.  And if another data transfer starts before
+	 * this bit comes to good sense (which eventually happens by
+	 * itself) then the new transfer simply fails with a timeout.
+	 */
+	if (!(mvsd_read(MVSD_HW_STATE) & (1 << 13))) {
+		unsigned long t = jiffies + HZ;
+		unsigned int hw_state,  count = 0;
+		do {
+			if (time_after(jiffies, t)) {
+				dev_warn(host->dev, "FIFO_EMPTY bit missing\n");
+				break;
+			}
+			hw_state = mvsd_read(MVSD_HW_STATE);
+			count++;
+		} while (!(hw_state & (1 << 13)));
+		dev_dbg(host->dev, "*** wait for FIFO_EMPTY bit "
+				   "(hw=0x%04x, count=%d, jiffies=%ld)\n",
+				   hw_state, count, jiffies - (t - HZ));
+	}
+
 	/* If timeout=0 then maximum timeout index is used. */
 	tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);
 	tmout += data->timeout_clks;

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

* Re: [PATCH] mvsdio: fix config failure with some high speed SDHC cards
  2009-05-27  2:35 [PATCH] mvsdio: fix config failure with some high speed SDHC cards Nicolas Pitre
@ 2009-05-27 20:26 ` Pierre Ossman
  0 siblings, 0 replies; 2+ messages in thread
From: Pierre Ossman @ 2009-05-27 20:26 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: lkml

[-- Attachment #1: Type: text/plain, Size: 1280 bytes --]

On Tue, 26 May 2009 22:35:34 -0400 (EDT)
Nicolas Pitre <nico@cam.org> wrote:

>     
> Especially with Sandisk SDHC cards, the second SWITCH command was failing
> with a timeout and the card was not recognized at all.  However if the
> system was busy, or debugging was enabled, or a udelay(100) was inserted
> before the second SWITCH command in the core code, then the timing was
> so that the card started to work.
> 
> This appears to be a problem with the host hardware.  With some unusual
> block sizes, the data FIFO status doesn't indicate a "empty" state right
> away when the data transfer is done.  Queuing another data transfer in
> that condition results in a transfer timeout.
> 
> The empty FIFO bit eventually get set by itself in less than 50 usecs
> when it is not set right away. So let's just poll for that bit before
> configuring the controller with a new data transfer.
> 
> Signed-off-by: Nicolas Pitre <nico@marvell.com>
> 

You seem to be having a lot of fun with this controller. :)

Patch queued.

Rgds
-- 
     -- Pierre Ossman

  WARNING: This correspondence is being monitored by the
  Swedish government. Make sure your server uses encryption
  for SMTP traffic and consider using PGP for end-to-end
  encryption.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

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

end of thread, other threads:[~2009-05-27 20:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-27  2:35 [PATCH] mvsdio: fix config failure with some high speed SDHC cards Nicolas Pitre
2009-05-27 20:26 ` Pierre Ossman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).