mmc: esdhc: fix errors when booting kernel on Freescale eSDHC version 2.3
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@freescale.com> Acked-by: Anton Vorontsov <cbouatmailru@gmail.com> Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
parent
3ec1e88b33
commit
ba8c4dc998
|
@ -38,6 +38,23 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg)
|
||||||
int base = reg & ~0x3;
|
int base = reg & ~0x3;
|
||||||
int shift = (reg & 0x3) * 8;
|
int shift = (reg & 0x3) * 8;
|
||||||
u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +73,21 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
|
||||||
|
|
||||||
static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
|
static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* "DMA select" location is offset 0x28 in SD specification, but on
|
||||||
|
* P5020 or P3041, it's located 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). */
|
/* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
|
||||||
if (reg == SDHCI_HOST_CONTROL)
|
if (reg == SDHCI_HOST_CONTROL)
|
||||||
val &= ~ESDHC_HOST_CONTROL_RES;
|
val &= ~ESDHC_HOST_CONTROL_RES;
|
||||||
|
|
Loading…
Reference in New Issue