aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSvyatoslav Ryhel <clamor95@gmail.com>2023-10-03 09:33:52 +0300
committerTom Rini <trini@konsulko.com>2023-11-03 12:37:15 -0400
commite1bbc5acefae97661614ba76c745b1d511006f8e (patch)
tree67aaee77af8613e126f79cfd55189ee5ef6d4c0b
parentcef7c062bf99454c1f7fdbb38a90b58a7a2ad13d (diff)
downloadu-boot-e1bbc5acefae97661614ba76c745b1d511006f8e.zip
u-boot-e1bbc5acefae97661614ba76c745b1d511006f8e.tar.gz
u-boot-e1bbc5acefae97661614ba76c745b1d511006f8e.tar.bz2
mmc: tegra: get default-tap and default-trim from device tree
Default-tap and default-trim values are used for eMMC setup mostly on T114+ devices. As for now, those values are hardcoded for T210 and ignored for all other Tegra generations. Fix this by passing tap and trim values from dts. Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
-rw-r--r--arch/arm/include/asm/arch-tegra/tegra_mmc.h17
-rw-r--r--drivers/mmc/tegra_mmc.c52
2 files changed, 36 insertions, 33 deletions
diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
index d6a5576..750c7d8 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
@@ -128,21 +128,22 @@ struct tegra_mmc {
/* SDMMC1/3 settings from SDMMCx Initialization Sequence of TRM */
#define MEMCOMP_PADCTRL_VREF 7
-#define AUTO_CAL_ENABLE (1 << 29)
-#define AUTO_CAL_ACTIVE (1 << 31)
-#define AUTO_CAL_START (1 << 31)
+#define AUTO_CAL_ENABLE BIT(29)
+#define AUTO_CAL_ACTIVE BIT(31)
+#define AUTO_CAL_START BIT(31)
+
#if defined(CONFIG_TEGRA210)
#define AUTO_CAL_PD_OFFSET (0x7D << 8)
#define AUTO_CAL_PU_OFFSET (0 << 0)
-#define IO_TRIM_BYPASS_MASK (1 << 2)
-#define TRIM_VAL_SHIFT 24
-#define TRIM_VAL_MASK (0x1F << TRIM_VAL_SHIFT)
-#define TAP_VAL_SHIFT 16
-#define TAP_VAL_MASK (0xFF << TAP_VAL_SHIFT)
#else
#define AUTO_CAL_PD_OFFSET (0x70 << 8)
#define AUTO_CAL_PU_OFFSET (0x62 << 0)
#endif
+#define TRIM_VAL_SHIFT 24
+#define TRIM_VAL_MASK (0x1F << TRIM_VAL_SHIFT)
+#define TAP_VAL_SHIFT 16
+#define TAP_VAL_MASK (0xFF << TAP_VAL_SHIFT)
+
#endif /* __ASSEMBLY__ */
#endif /* __TEGRA_MMC_H_ */
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index f76fee3..d507adb 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -37,6 +37,9 @@ struct tegra_mmc_priv {
unsigned int version; /* SDHCI spec. version */
unsigned int clock; /* Current clock (MHz) */
int mmc_id; /* peripheral id */
+
+ int tap_value;
+ int trim_value;
};
static void tegra_mmc_set_power(struct tegra_mmc_priv *priv,
@@ -526,31 +529,6 @@ static void tegra_mmc_pad_init(struct tegra_mmc_priv *priv)
printf("%s: Warning: Autocal timed out!\n", __func__);
/* TBD: Set CFG2TMC_SDMMC1_PAD_CAL_DRV* regs here */
}
-
-#if defined(CONFIG_TEGRA210)
- u32 tap_value, trim_value;
-
- /* Set tap/trim values for SDMMC1/3 @ <48MHz here */
- val = readl(&priv->reg->venspictl); /* aka VENDOR_SYS_SW_CNTL */
- val &= IO_TRIM_BYPASS_MASK;
- if (id == PERIPH_ID_SDMMC1) {
- tap_value = 4; /* default */
- if (val)
- tap_value = 3;
- trim_value = 2;
- } else { /* SDMMC3 */
- tap_value = 3;
- trim_value = 3;
- }
-
- val = readl(&priv->reg->venclkctl);
- val &= ~TRIM_VAL_MASK;
- val |= (trim_value << TRIM_VAL_SHIFT);
- val &= ~TAP_VAL_MASK;
- val |= (tap_value << TAP_VAL_SHIFT);
- writel(val, &priv->reg->venclkctl);
- debug("%s: VENDOR_CLOCK_CNTRL = 0x%08X\n", __func__, val);
-#endif /* T210 */
#endif /* T30/T210 */
}
@@ -588,6 +566,22 @@ static void tegra_mmc_reset(struct tegra_mmc_priv *priv, struct mmc *mmc)
/* Make sure SDIO pads are set up */
tegra_mmc_pad_init(priv);
+
+ if (!IS_ERR_VALUE(priv->tap_value) ||
+ !IS_ERR_VALUE(priv->trim_value)) {
+ u32 val;
+
+ val = readl(&priv->reg->venclkctl);
+
+ val &= ~TRIM_VAL_MASK;
+ val |= (priv->trim_value << TRIM_VAL_SHIFT);
+
+ val &= ~TAP_VAL_MASK;
+ val |= (priv->tap_value << TAP_VAL_SHIFT);
+
+ writel(val, &priv->reg->venclkctl);
+ debug("%s: VENDOR_CLOCK_CNTRL = 0x%08X\n", __func__, val);
+ }
}
static int tegra_mmc_init(struct udevice *dev)
@@ -742,6 +736,14 @@ static int tegra_mmc_probe(struct udevice *dev)
if (dm_gpio_is_valid(&priv->pwr_gpio))
dm_gpio_set_value(&priv->pwr_gpio, 1);
+ ret = dev_read_u32(dev, "nvidia,default-tap", &priv->tap_value);
+ if (ret)
+ priv->tap_value = ret;
+
+ ret = dev_read_u32(dev, "nvidia,default-trim", &priv->trim_value);
+ if (ret)
+ priv->trim_value = ret;
+
upriv->mmc = &plat->mmc;
return tegra_mmc_init(dev);