int drive_group_sel;
bool en_strobe;
unsigned int tuned_tap_delay;
+ unsigned int tuning_status;
+#define TUNING_STATUS_DONE 1
+#define TUNING_STATUS_RETUNE 2
struct padctrl *sdmmc_padctrl;
ktime_t timestamp;
struct regulator *vdd_io_reg;
SDMMC_VENDOR_ERR_INTR_STATUS_0));
}
+static bool tegra_sdhci_is_tuning_done(struct sdhci_host *sdhci)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci);
+ struct sdhci_tegra *tegra_host = pltfm_host->priv;
+
+ if (tegra_host->tuning_status == TUNING_STATUS_DONE) {
+ dev_info(mmc_dev(sdhci->mmc),
+ "Tuning already done, restoring the best tap value : %u\n",
+ tegra_host->tuned_tap_delay);
+ sdhci_tegra_set_tap_delay(sdhci, tegra_host->tuned_tap_delay);
+ return true;
+ }
+ return false;
+}
+
static int sdhci_tegra_get_max_tuning_loop_counter(struct sdhci_host *sdhci)
{
u16 hw_tuning_iterations;
if (plat->uhs_mask & MMC_MASK_HS400)
host->mmc->caps2 &= ~MMC_CAP2_HS400;
+
+ if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ tegra_host->tuning_status = TUNING_STATUS_RETUNE;
}
static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
tap_delay >>= SDHCI_VNDR_CLK_CTRL_TAP_VALUE_SHIFT;
tap_delay &= SDHCI_VNDR_CLK_CTRL_TAP_VALUE_MASK;
tegra_host->tuned_tap_delay = tap_delay;
+ tegra_host->tuning_status = TUNING_STATUS_DONE;
break;
case SET_DEFAULT_TAP:
sdhci_tegra_set_tap_delay(sdhci, tegra_host->plat->tap_delay);
.config_tap_delay = tegra_sdhci_config_tap,
.validate_sd2_0 = tegra_sdhci_validate_sd2_0,
.get_max_pio_transfer_limits = tegra_sdhci_set_max_pio_transfer_limits,
+ .is_tuning_done = tegra_sdhci_is_tuning_done,
};
static const struct sdhci_pltfm_data sdhci_tegra124_pdata = {
.quirks2 = TEGRA_SDHCI_QUIRKS2 |
SDHCI_QUIRK2_NON_STD_TUN_CARD_CLOCK |
SDHCI_QUIRK2_NON_STD_TUNING_LOOP_CNTR |
+ SDHCI_QUIRK2_SKIP_TUNING |
SDHCI_QUIRK2_PERIODIC_CALIBRATION,
.ops = &tegra_sdhci_ops,
};
.quirks2 = TEGRA_SDHCI_QUIRKS2 |
SDHCI_QUIRK2_NON_STD_TUN_CARD_CLOCK |
SDHCI_QUIRK2_NON_STD_TUNING_LOOP_CNTR |
+ SDHCI_QUIRK2_SKIP_TUNING |
SDHCI_QUIRK2_PERIODIC_CALIBRATION,
.ops = &tegra_sdhci_ops,
};
sdhci_runtime_pm_get(host);
spin_lock_irqsave(&host->lock, flags);
+ if ((host->quirks2 & SDHCI_QUIRK2_SKIP_TUNING) &&
+ host->ops->is_tuning_done) {
+ if(host->ops->is_tuning_done(host)) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ sdhci_runtime_pm_put(host);
+ return 0;
+ }
+ }
+
if ((host->quirks2 & SDHCI_QUIRK2_NON_STD_TUNING_LOOP_CNTR) &&
(host->ops->get_max_tuning_loop_counter))
tuning_loop_counter =