mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 14:10:43 +00:00
mmc: t210: Fix 'bad' SD-card clock when doing 400KHz card detect
According to the HW team, for some reason the normal clock select code picks what appears to be a perfectly valid 375KHz SD card clock, based on the CAR clock source and SDMMC1 controller register settings (CAR = 408MHz PLLP0 divided by 68 for 6MHz, then a SD Clock Control register divisor of 16 = 375KHz). But the resulting SD card clock, as measured by the HW team, is 700KHz, which is out-of-spec. So the WAR is to use the values given in the TRM PLLP table to generate a 400KHz SD-clock (CAR clock of 24.7MHz, SD Clock Control divisor of 62) only for SDMMC1 on T210 when the requested clock is <= 400KHz. Note that as far as I can tell, the other requests for clocks in the Tegra MMC driver result in valid SD clocks. Signed-off-by: Tom Warren <twarren@nvidia.com> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
This commit is contained in:
parent
5e965e8140
commit
a482f32992
2 changed files with 20 additions and 1 deletions
|
@ -130,9 +130,9 @@ struct tegra_mmc {
|
|||
/* SDMMC1/3 settings from SDMMCx Initialization Sequence of TRM */
|
||||
#define MEMCOMP_PADCTRL_VREF 7
|
||||
#define AUTO_CAL_ENABLE (1 << 29)
|
||||
#if defined(CONFIG_TEGRA210)
|
||||
#define AUTO_CAL_ACTIVE (1 << 31)
|
||||
#define AUTO_CAL_START (1 << 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)
|
||||
|
|
|
@ -376,6 +376,25 @@ static void tegra_mmc_change_clock(struct tegra_mmc_priv *priv, uint clock)
|
|||
|
||||
rate = clk_set_rate(&priv->clk, clock);
|
||||
div = (rate + clock - 1) / clock;
|
||||
|
||||
#if defined(CONFIG_TEGRA210)
|
||||
if (priv->mmc_id == PERIPH_ID_SDMMC1 && clock <= 400000) {
|
||||
/* clock_adjust_periph_pll_div() chooses a 'bad' clock
|
||||
* on SDMMC1 T210, so skip it here and force a clock
|
||||
* that's been spec'd in the table in the TRM for
|
||||
* card-detect (400KHz).
|
||||
*/
|
||||
uint effective_rate = clock_adjust_periph_pll_div(priv->mmc_id,
|
||||
CLOCK_ID_PERIPH, 24727273, NULL);
|
||||
div = 62;
|
||||
|
||||
debug("%s: WAR: Using SDMMC1 clock of %u, div %d to achieve %dHz card clock ...\n",
|
||||
__func__, effective_rate, div, clock);
|
||||
} else {
|
||||
clock_adjust_periph_pll_div(priv->mmc_id, CLOCK_ID_PERIPH,
|
||||
clock, &div);
|
||||
}
|
||||
#endif
|
||||
debug("div = %d\n", div);
|
||||
|
||||
writew(0, &priv->reg->clkcon);
|
||||
|
|
Loading…
Reference in a new issue