linux-mmc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH resend] sdhci: work around broken dma boundary behaviour
@ 2011-03-07 20:40 Mikko Vinni
  2011-03-08 20:12 ` Chris Ball
  2011-03-12 21:43 ` Wolfram Sang
  0 siblings, 2 replies; 15+ messages in thread
From: Mikko Vinni @ 2011-03-07 20:40 UTC (permalink / raw)
  To: linux-mmc; +Cc: Mikko Vinni

Some SD host controllers (noticed on an integrated JMicron SD reader
on an HP Pavilion dv5-1250eo laptop) don't update the dma address
register before signaling a dma interrupt due to a dma boundary.
Detect this and update the register to the next 512KB boundary,
at which the transfer presumably stopped.

As long as each transfer is at most 512KB in size (on this hardware
the max seems to be 65536 bytes), this fix is needed at most once
per transfer.

Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=28462

Signed-off-by: Mikko Vinni <mmvinni <at> yahoo.com>
---
Sent on 2011-02-21 21:23:32 GMT
(http://thread.gmane.org/gmane.linux.kernel.mmc/5568/focus=6145)

Hoping to be able to drop this patch eventually from my own
repo and have the hardware just work with mainline code.
Maybe first in -next if nobody sees any serious problems
straight away?

This patch should not break anything for anybody whose
hardware isn't already broken.

 drivers/mmc/host/sdhci.c |   24 +++++++++++++++++++++---
 1 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a25db42..8651731 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1537,9 +1537,27 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
 		 * boundaries, but as we can't disable the feature
 		 * we need to at least restart the transfer.
 		 */
-		if (intmask & SDHCI_INT_DMA_END)
-			sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
-				SDHCI_DMA_ADDRESS);
+		if (intmask & SDHCI_INT_DMA_END) {
+			u32 dmastart, dmanow;
+			dmastart = sg_dma_address(host->data->sg);
+			dmanow = sdhci_readl(host, SDHCI_DMA_ADDRESS);
+			if (dmanow == dmastart) {
+				/*
+				 * HW failed to increase the address.
+				 * Update to the next 512KB block boundary.
+				 */
+				dmanow = (dmanow & ~0x7ffff) + 0x80000;
+				if (dmanow > dmastart + host->data->blksz *
+							host->data->blocks) {
+					WARN_ON(1);
+					dmanow = dmastart;
+				}
+				DBG("%s: next DMA address forced "
+				    "from 0x%08x to 0x%08x\n",
+				    mmc_hostname(host->mmc), dmastart, dmanow);
+			}
+			sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+		}
 
 		if (intmask & SDHCI_INT_DATA_END) {
 			if (host->cmd) {
-- 
1.7.4.1


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

end of thread, other threads:[~2011-04-13  7:04 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-07 20:40 [PATCH resend] sdhci: work around broken dma boundary behaviour Mikko Vinni
2011-03-08 20:12 ` Chris Ball
2011-03-08 22:12   ` Wolfram Sang
2011-03-12 21:43 ` Wolfram Sang
2011-03-14  9:23   ` Mikko Vinni
2011-03-14 10:18     ` Wolfram Sang
2011-03-14 13:00       ` Mikko Vinni
2011-03-14 15:28         ` Wolfram Sang
2011-03-14 15:58           ` Mikko Vinni
2011-03-14 17:21             ` Wolfram Sang
2011-03-29  8:53               ` [RFC] mmc: sdhci: work around broken dma boundary behavior Mikko Vinni
2011-04-11 21:05                 ` Chris Ball
2011-04-12  4:56                   ` Wolfram Sang
2011-04-12 17:29                 ` Chris Ball
2011-04-13  7:04                   ` Mikko Vinni

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