diff options
author | Lucas Stach <dev@lynxeye.de> | 2014-05-14 22:45:40 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-05-15 14:17:12 +0200 |
commit | ce41b642998f64815f364f5d10df952503fd426e (patch) | |
tree | 0a4c41dc46403c37ee19de0e1f6b128482b930e3 /drivers/mci/tegra-sdmmc.c | |
parent | 1fc137d4cdd462e47a9f2c55c3649cf608df6482 (diff) | |
download | barebox-ce41b642998f64815f364f5d10df952503fd426e.tar.gz barebox-ce41b642998f64815f364f5d10df952503fd426e.tar.xz |
mci: tegra: apply pad autocalibration on T30
Needed for SD cards connected to sdmmc1 or sdmmc3
to work properly.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mci/tegra-sdmmc.c')
-rw-r--r-- | drivers/mci/tegra-sdmmc.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/mci/tegra-sdmmc.c b/drivers/mci/tegra-sdmmc.c index 0ea0b5ca4a..634515705f 100644 --- a/drivers/mci/tegra-sdmmc.c +++ b/drivers/mci/tegra-sdmmc.c @@ -59,6 +59,14 @@ #define TEGRA_SDMMC_INT_SIG_EN 0x038 #define TEGRA_SDMMC_INT_SIG_EN_XFER_COMPLETE (1 << 1) +#define TEGRA_SDMMC_SDMEMCOMPPADCTRL 0x1e0 +#define TEGRA_SDMMC_SDMEMCOMPPADCTRL_VREF_SEL_SHIFT 0 + +#define TEGRA_SDMMC_AUTO_CAL_CONFIG 0x1e4 +#define TEGRA_SDMMC_AUTO_CAL_CONFIG_PU_OFFSET_SHIFT 0 +#define TEGRA_SDMMC_AUTO_CAL_CONFIG_PD_OFFSET_SHIFT 8 +#define TEGRA_SDMMC_AUTO_CAL_CONFIG_ENABLE (1 << 29) + struct tegra_sdmmc_host { struct mci_host mci; void __iomem *regs; @@ -333,6 +341,23 @@ static int tegra_sdmmc_init(struct mci_host *mci, struct device_d *dev) val |= TEGRA_SDMMC_PWR_CNTL_33_V | TEGRA_SDMMC_PWR_CNTL_SD_BUS; writel(val, regs + TEGRA_SDMMC_PWR_CNTL); + /* sdmmc1 and sdmmc3 on T30 need a bit of padctrl init */ + if (of_device_is_compatible(mci->hw_dev->device_node, + "nvidia,tegra30-sdhci") && + ((u32)regs == 0x78000000 || (u32)regs == 78000400)) { + val = readl(regs + TEGRA_SDMMC_SDMEMCOMPPADCTRL); + val &= 0xfffffff0; + val |= 0x7 << TEGRA_SDMMC_SDMEMCOMPPADCTRL_VREF_SEL_SHIFT; + writel(val, regs + TEGRA_SDMMC_SDMEMCOMPPADCTRL); + + val = readl(regs + TEGRA_SDMMC_AUTO_CAL_CONFIG); + val &= 0xffff0000; + val |= (0x62 << TEGRA_SDMMC_AUTO_CAL_CONFIG_PU_OFFSET_SHIFT) | + (0x70 << TEGRA_SDMMC_AUTO_CAL_CONFIG_PD_OFFSET_SHIFT) | + TEGRA_SDMMC_AUTO_CAL_CONFIG_ENABLE; + writel(val, regs + TEGRA_SDMMC_AUTO_CAL_CONFIG); + } + /* setup signaling */ writel(0xffffffff, regs + TEGRA_SDMMC_INT_STAT_EN); writel(0xffffffff, regs + TEGRA_SDMMC_INT_SIG_EN); |