Skip to content

Commit 4a82261

Browse files
committed
mmc: sdhci-of-at91: add support for HS400 and HS400ES
Add support for HS400 and HS400ES timings. Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
1 parent 301a943 commit 4a82261

1 file changed

Lines changed: 40 additions & 3 deletions

File tree

drivers/mmc/host/sdhci-of-at91.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#define SDMMC_MC1R_DDR BIT(3)
2828
#define SDMMC_MC1R_RSTN BIT(6)
2929
#define SDMMC_MC1R_FCD BIT(7)
30+
#define SDMMC_MC3R 0x206
31+
#define SDMMC_MC3R_HS400EN BIT(0)
32+
#define SDMMC_MC3R_ESMEN BIT(1)
3033
#define SDMMC_CACR 0x230
3134
#define SDMMC_CACR_CAPWREN BIT(0)
3235
#define SDMMC_CACR_KEY (0x46 << 8)
@@ -103,14 +106,32 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
103106
static void sdhci_at91_set_uhs_signaling(struct sdhci_host *host,
104107
unsigned int timing)
105108
{
106-
u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
109+
u16 clk;
110+
u8 mc3r, mc1r;
111+
112+
mc1r = readb(host->ioaddr + SDMMC_MC1R);
113+
mc3r = readb(host->ioaddr + SDMMC_MC3R);
114+
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
115+
107116
/* SDCLK must be disabled while changing the mode */
108117
if (clk & SDHCI_CLOCK_CARD_EN)
109118
sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN,
110119
SDHCI_CLOCK_CONTROL);
111120

112-
if (timing == MMC_TIMING_MMC_DDR52)
113-
sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R);
121+
if (timing == MMC_TIMING_MMC_DDR52 || timing == MMC_TIMING_MMC_HS400)
122+
mc1r |= SDMMC_MC1R_DDR;
123+
else
124+
mc1r &= ~SDMMC_MC1R_DDR;
125+
126+
sdhci_writeb(host, mc1r, SDMMC_MC1R);
127+
128+
if (timing == MMC_TIMING_MMC_HS400)
129+
mc3r |= SDMMC_MC3R_HS400EN;
130+
else
131+
mc3r &= ~SDMMC_MC3R_HS400EN;
132+
133+
writeb(mc3r, host->ioaddr + SDMMC_MC3R);
134+
114135
sdhci_set_uhs_signaling(host, timing);
115136

116137
/* reenable SDCLK */
@@ -362,6 +383,20 @@ static const struct dev_pm_ops sdhci_at91_dev_pm_ops = {
362383
NULL)
363384
};
364385

386+
static void at91_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios)
387+
{
388+
struct sdhci_host *host = mmc_priv(mmc);
389+
u8 mc3r;
390+
391+
mc3r = readb(host->ioaddr + SDMMC_MC3R);
392+
if (ios->enhanced_strobe)
393+
mc3r |= SDMMC_MC3R_ESMEN;
394+
else
395+
mc3r &= ~SDMMC_MC3R_ESMEN;
396+
397+
writeb(mc3r, host->ioaddr + SDMMC_MC3R);
398+
}
399+
365400
static int sdhci_at91_probe(struct platform_device *pdev)
366401
{
367402
const struct of_device_id *match;
@@ -446,6 +481,8 @@ static int sdhci_at91_probe(struct platform_device *pdev)
446481
if (ret)
447482
goto pm_runtime_disable;
448483

484+
host->mmc_host_ops.hs400_enhanced_strobe = at91_sdhci_hs400_enhanced_strobe;
485+
449486
/*
450487
* When calling sdhci_runtime_suspend_host(), the sdhci layer makes
451488
* the assumption that all the clocks of the controller are disabled.

0 commit comments

Comments
 (0)