Commit 212b0cf1 authored by Aapo Vienamo's avatar Aapo Vienamo Committed by Ulf Hansson

mmc: tegra: Power on the calibration pad

Automatic pad drive strength calibration is performed on a separate pad
identical to the ones used for driving the actual bus. Power on the
calibration pad during the calibration procedure and power it off
afterwards to save power.
Signed-off-by: default avatarAapo Vienamo <avienamo@nvidia.com>
Reviewed-by: default avatarMikko Perttunen <mperttunen@nvidia.com>
Acked-by: default avatarThierry Reding <treding@nvidia.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 9d548f11
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL 0x1e0 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL 0x1e0
#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK 0x0000000f #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK 0x0000000f
#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL 0x7 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL 0x7
#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD BIT(31)
#define SDHCI_TEGRA_AUTO_CAL_STATUS 0x1ec #define SDHCI_TEGRA_AUTO_CAL_STATUS 0x1ec
#define SDHCI_TEGRA_AUTO_CAL_ACTIVE BIT(31) #define SDHCI_TEGRA_AUTO_CAL_ACTIVE BIT(31)
...@@ -238,11 +239,34 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask) ...@@ -238,11 +239,34 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
tegra_host->ddr_signaling = false; tegra_host->ddr_signaling = false;
} }
static void tegra_sdhci_configure_cal_pad(struct sdhci_host *host, bool enable)
{
u32 val;
/*
* Enable or disable the additional I/O pad used by the drive strength
* calibration process.
*/
val = sdhci_readl(host, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
if (enable)
val |= SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD;
else
val &= ~SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD;
sdhci_writel(host, val, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
if (enable)
usleep_range(1, 2);
}
static void tegra_sdhci_pad_autocalib(struct sdhci_host *host) static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
{ {
u32 reg; u32 reg;
int ret; int ret;
tegra_sdhci_configure_cal_pad(host, true);
reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG); reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
reg |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START; reg |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG); sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
...@@ -253,6 +277,8 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host) ...@@ -253,6 +277,8 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
reg, !(reg & SDHCI_TEGRA_AUTO_CAL_ACTIVE), reg, !(reg & SDHCI_TEGRA_AUTO_CAL_ACTIVE),
1000, 10000); 1000, 10000);
tegra_sdhci_configure_cal_pad(host, false);
if (ret) if (ret)
dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n"); dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment