]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
mmc: tegra: Always enable calibration
authorPavan Kunapuli <pkunapuli@nvidia.com>
Wed, 28 Aug 2013 15:14:14 +0000 (20:44 +0530)
committerPavan Kunapuli <pkunapuli@nvidia.com>
Tue, 5 May 2015 12:07:29 +0000 (05:07 -0700)
Do not disable calibration unless NVQUIRK_SET_DRIVE_STRENGTH is set
which means the drive strength codes would be updated in the pad ctrl
registers and the same would be sent to the pads.

Bug 1357541

Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-on: http://git-master/r/267403
(cherry picked from commit 4ea1e5f3ff1270d24f2401dca86d0bd25db4cb80)
Change-Id: I2574e412859b3c2e0214ebf996f0459dcda4b139
Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-on: http://git-master/r/739071
Reviewed-by: Automatic_Commit_Validation_User
drivers/mmc/host/sdhci-tegra.c

index 2670672f15e2d94af3b83fb10b9d190d11a0dd36..83b5e26fdd2216f86ecac9116237aef0473e932f 100644 (file)
@@ -599,16 +599,49 @@ static void tegra_sdhci_do_calibration(struct sdhci_host *sdhci)
        if (!timeout)
                dev_err(mmc_dev(sdhci->mmc), "Auto calibration failed\n");
 
-       /* Disable Auto calibration */
-       val = sdhci_readl(sdhci, SDMMC_AUTO_CAL_CONFIG);
-       val &= ~SDMMC_AUTO_CAL_CONFIG_AUTO_CAL_ENABLE;
-       sdhci_writel(sdhci, val, SDMMC_AUTO_CAL_CONFIG);
-
        if (soc_data->nvquirks & NVQUIRK_SET_PAD_E_INPUT_OR_E_PWRD) {
                val = sdhci_readl(sdhci, SDMMC_SDMEMCOMPPADCTRL);
                val &= ~SDMMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD_MASK;
                sdhci_writel(sdhci, val, SDMMC_SDMEMCOMPPADCTRL);
        }
+
+       if (unlikely(soc_data->nvquirks & NVQUIRK_SET_DRIVE_STRENGTH)) {
+               unsigned int pulldown_code;
+               unsigned int pullup_code;
+               int pg;
+               int err;
+
+               /* Disable Auto calibration */
+               val = sdhci_readl(sdhci, SDMMC_AUTO_CAL_CONFIG);
+               val &= ~SDMMC_AUTO_CAL_CONFIG_AUTO_CAL_ENABLE;
+               sdhci_writel(sdhci, val, SDMMC_AUTO_CAL_CONFIG);
+
+               pg = tegra_drive_get_pingroup(mmc_dev(sdhci->mmc));
+               if (pg != -1) {
+                       /* Get the pull down codes from auto cal status reg */
+                       pulldown_code = (
+                               sdhci_readl(sdhci, SDMMC_AUTO_CAL_STATUS) >>
+                               SDMMC_AUTO_CAL_STATUS_PULLDOWN_OFFSET);
+                       /* Set the pull down in the pinmux reg */
+                       err = tegra_drive_pinmux_set_pull_down(pg,
+                               pulldown_code);
+                       if (err)
+                               dev_err(mmc_dev(sdhci->mmc),
+                               "Failed to set pulldown codes %d err %d\n",
+                               pulldown_code, err);
+
+                       /* Calculate the pull up codes */
+                       pullup_code = pulldown_code + PULLUP_ADJUSTMENT_OFFSET;
+                       if (pullup_code >= TEGRA_MAX_PULL)
+                               pullup_code = TEGRA_MAX_PULL - 1;
+                       /* Set the pull up code in the pinmux reg */
+                       err = tegra_drive_pinmux_set_pull_up(pg, pullup_code);
+                       if (err)
+                               dev_err(mmc_dev(sdhci->mmc),
+                               "Failed to set pullup codes %d err %d\n",
+                               pullup_code, err);
+               }
+       }
 }
 
 static int sdhci_tegra_sd_error_stats(struct sdhci_host *host, u32 int_status)