[PATCH][upstream] eSDHC: fix errors when booting kernel on Freescale eSDHC version 2.3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Roy Zang <roy@royamd64.(none)>

When eSDHC module is enabled on P5020/P3041/P2041/P1010 with eSDHC
version 2.3, there is following errors:

mmc0: Timeout waiting for hardware interrupt.
mmc0: error -110 whilst initialising SD card
mmc0: Unexpected interrupt 0x02000000.
mmc0: Timeout waiting for hardware interrupt.
mmc0: error -110 whilst initialising SD card
mmc0: Unexpected interrupt 0x02000000.

It is because eSDHC controller has different bit setting for PROCTL
register at 0x28 comparing SD specification.
This patch sets DMAS bits correctly for byte operation and does not
change the default value of other field of PROCTL register.

For other FSL chips, such as MPC8536/P2020, PROCTL[DMAS]
bits are reserved and even if they are set to wrong bits, it will not
take effective.

Signed-off-by: Roy Zang <tie-fei.zang@xxxxxxxxxxxxx>
Cc: Lei Xu <B33228@xxxxxxxxxxxxx>
Cc: Jerry Huang <Chang-Ming.Huang@xxxxxxxxxxxxx>
Cc: Anton Vorontsov <cbouatmailru@xxxxxxxxx>
Cc: Priyanka Jain <Priyanka.Jain@xxxxxxxxxxxxx>
---
this is a replacemnet patch for 
http://patchwork.ozlabs.org/patch/103184/
or
http://permalink.gmane.org/gmane.linux.kernel.mmc/12066

according to feedback
http://article.gmane.org/gmane.linux.kernel.mmc/12072/match=c+must+know+nothing+esdhc+registers
and 
http://lists.ozlabs.org/pipermail/linuxppc-dev/2011-August/092402.html

Tested on P3041/P5020 and P4080
 drivers/mmc/host/sdhci-of-esdhc.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 01e5f62..36caad3 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -38,6 +38,22 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg)
 	int base = reg & ~0x3;
 	int shift = (reg & 0x3) * 8;
 	u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff;
+
+	/*
+	 * "DMA select" locates at offset 0x28 in SD specification, but on
+	 * P5020 or P3041, it locates at 0x29.
+	 */
+	if (reg == SDHCI_HOST_CONTROL) {
+		u32 dma_bits;
+		dma_bits = in_be32(host->ioaddr + reg);
+		/* DMA select is 22,23 bits in Protocol Control Register*/
+		dma_bits = (dma_bits >> 5) & SDHCI_CTRL_DMA_MASK;
+
+		/* fixup the result */
+		ret &= ~SDHCI_CTRL_DMA_MASK;
+		ret |= dma_bits;
+	}
+
 	return ret;
 }
 
@@ -56,6 +72,20 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
 
 static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
 {
+	/*
+	 * "DMA select" locates at offset 0x28 in SD specification, but on
+	 * P5020 or P3041, it locates at 0x29.
+	 */
+	if (reg == SDHCI_HOST_CONTROL) {
+		u32 dma_bits;
+		/* DMA select is 22,23 bits in Protocol Control Register*/
+		dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5;
+		clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5,
+			dma_bits);
+		val &= ~SDHCI_CTRL_DMA_MASK;
+		val |= (in_be32(host->ioaddr + reg) & SDHCI_CTRL_DMA_MASK);
+	}
+
 	/* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
 	if (reg == SDHCI_HOST_CONTROL)
 		val &= ~ESDHC_HOST_CONTROL_RES;
-- 
1.7.0.4


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux