diff options
Diffstat (limited to 'drivers/mmc/host/sdhci-esdhc.h')
-rw-r--r-- | drivers/mmc/host/sdhci-esdhc.h | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index a2a0642..7725160 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -23,16 +23,22 @@ SDHCI_QUIRK_NONSTANDARD_CLOCK | \ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \ SDHCI_QUIRK_PIO_NEEDS_DELAY | \ - SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) + SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | \ + SDHCI_QUIRK_NO_HISPD_BIT) #define ESDHC_SYSTEM_CONTROL 0x2c #define ESDHC_CLOCK_MASK 0x0000fff0 #define ESDHC_PREDIV_SHIFT 8 #define ESDHC_DIVIDER_SHIFT 4 +#define ESDHC_CLOCK_CRDEN 0x00000008 #define ESDHC_CLOCK_PEREN 0x00000004 #define ESDHC_CLOCK_HCKEN 0x00000002 #define ESDHC_CLOCK_IPGEN 0x00000001 + +#define ESDHCI_PRESENT_STATE 0x24 +#define ESDHC_CLK_STABLE 0x00000008 + /* pltfm-specific */ #define ESDHC_HOST_CONTROL_LE 0x20 @@ -46,12 +52,15 @@ /* OF-specific */ #define ESDHC_DMA_SYSCTL 0x40c #define ESDHC_DMA_SNOOP 0x00000040 +#define ESDHC_INT_DMA_ERROR 0x10000000 -#define ESDHC_HOST_CONTROL_RES 0x05 +#define ESDHC_HOST_CONTROL_RES 0x01 +#define ESDHC_VOL_SEL 0x04 static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock, unsigned int host_clock) { + u32 timeout; int pre_div = 2; int div = 1; u32 temp; @@ -81,6 +90,22 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock, | (div << ESDHC_DIVIDER_SHIFT) | (pre_div << ESDHC_PREDIV_SHIFT)); sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); + + /* Wait max 20 ms */ + timeout = 20; + while (!(sdhci_readl(host, ESDHCI_PRESENT_STATE) & ESDHC_CLK_STABLE)) { + if (timeout == 0) { + pr_err("%s: Internal clock never " + "stabilised.\n", mmc_hostname(host->mmc)); + return; + } + timeout--; + mdelay(1); + } + + temp |= ESDHC_CLOCK_CRDEN; + sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); + mdelay(1); out: host->clock = clock; |