Skip to content

Commit

Permalink
mmc: esdhc: fix errors when booting kernel on Freescale eSDHC version…
Browse files Browse the repository at this point in the history
… 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>
  • Loading branch information
Roy Zang authored and Chris Ball committed Feb 12, 2012
1 parent 3ec1e88 commit ba8c4dc
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions drivers/mmc/host/sdhci-of-esdhc.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ 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;
}

Expand All @@ -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)
{
/*
* "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). */
if (reg == SDHCI_HOST_CONTROL)
val &= ~ESDHC_HOST_CONTROL_RES;
Expand Down

0 comments on commit ba8c4dc

Please sign in to comment.