#define SDHCI_VNDR_CAP_OVERRIDES_0_DQS_TRIM_SHIFT 8
#define SDHCI_VNDR_CAP_OVERRIDES_0_DQS_TRIM_MASK 0x3F
+#define SDHCI_VNDR_DLLCAL_CFG 0x1b0
+#define SDHCI_VNDR_DLLCAL_CFG_EN_CALIBRATE 0x10000000
+
+#define SDHCI_VNDR_DLLCAL_CFG_STATUS 0x1bc
+#define SDHCI_VNDR_DLLCAL_CFG_STATUS_DLL_ACTIVE 0x10000000
+
#define SDHCI_VNDR_TUN_CTRL 0x1c0
/* Enable Re-tuning request only when CRC error is detected
* in SDR50/SDR104/HS200 modes
int drive_group_sel;
};
+static unsigned long get_nearest_clock_freq(unsigned long pll_rate,
+ unsigned long desired_rate);
+static inline int sdhci_tegra_set_tap_delay(struct sdhci_host *sdhci,
+ unsigned int tap_delay);
+static inline int sdhci_tegra_set_trim_delay(struct sdhci_host *sdhci,
+ unsigned int trim_delay);
+static inline int sdhci_tegra_set_dqs_trim_delay(struct sdhci_host *sdhci,
+ unsigned int dqs_trim_delay);
+static void tegra_sdhci_do_calibration(struct sdhci_host *sdhci,
+ unsigned char signal_voltage);
+static void tegra_sdhci_do_dll_calibration(struct sdhci_host *sdhci);
+
static int show_error_stats_dump(struct seq_file *s, void *data)
{
struct sdhci_host *host = s->private;
mutex_unlock(&tegra_host->set_clock_mutex);
}
+static void tegra_sdhci_do_dll_calibration(struct sdhci_host *sdhci)
+{
+ u32 dll_cfg;
+ unsigned timeout = 5;
+
+ dll_cfg = sdhci_readl(sdhci, SDHCI_VNDR_DLLCAL_CFG);
+ dll_cfg |= SDHCI_VNDR_DLLCAL_CFG_EN_CALIBRATE;
+ sdhci_writel(sdhci, dll_cfg, SDHCI_VNDR_DLLCAL_CFG);
+
+ mdelay(1);
+
+ /* Wait until the dll calibration is done */
+ do {
+ if (!(sdhci_readl(sdhci, SDHCI_VNDR_DLLCAL_CFG_STATUS) &
+ SDHCI_VNDR_DLLCAL_CFG_STATUS_DLL_ACTIVE))
+ break;
+
+ mdelay(1);
+ timeout--;
+ } while (timeout);
+
+ if (!timeout) {
+ dev_err(mmc_dev(sdhci->mmc), "DLL calibration is failed\n");
+ }
+}
+
static void tegra_sdhci_do_calibration(struct sdhci_host *sdhci,
unsigned char signal_voltage)
{
}
}
+/* Execute DLL calibration once for MMC device if it is
+ * enumerated in HS400 mode at 200MHz clock freq before
+ * starting any data transfer.
+ */
+static void sdhci_post_init(struct mmc_host *mmc)
+{
+ struct sdhci_host *host;
+
+ host = mmc_priv(mmc);
+
+ if (host->ops->post_init)
+ host->ops->post_init(host);
+}
/*****************************************************************************\
* *
* MMC callbacks *
.card_event = sdhci_card_event,
.card_busy = sdhci_card_busy,
.select_drive_strength = sdhci_select_drive_strength,
+ .post_init = sdhci_post_init,
};
/*****************************************************************************\