break;
case UHS_SDR104:
case MMC_HS_200:
+ case MMC_HS_400:
ret = pinctrl_select_state(dev, "state_200mhz");
break;
default:
}
}
+static void esdhc_set_strobe_dll(struct mmc *mmc)
+{
+ struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
+ struct fsl_esdhc *regs = priv->esdhc_regs;
+ u32 val;
+
+ if (priv->clock > ESDHC_STROBE_DLL_CLK_FREQ) {
+ writel(ESDHC_STROBE_DLL_CTRL_RESET, ®s->strobe_dllctrl);
+
+ /*
+ * enable strobe dll ctrl and adjust the delay target
+ * for the uSDHC loopback read clock
+ */
+ val = ESDHC_STROBE_DLL_CTRL_ENABLE |
+ (priv->strobe_dll_delay_target <<
+ ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
+ writel(val, ®s->strobe_dllctrl);
+ /* wait 1us to make sure strobe dll status register stable */
+ mdelay(1);
+ val = readl(®s->strobe_dllstat);
+ if (!(val & ESDHC_STROBE_DLL_STS_REF_LOCK))
+ pr_warn("HS400 strobe DLL status REF not lock!\n");
+ if (!(val & ESDHC_STROBE_DLL_STS_SLV_LOCK))
+ pr_warn("HS400 strobe DLL status SLV not lock!\n");
+ }
+}
+
static int esdhc_set_timing(struct mmc *mmc)
{
struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
case MMC_LEGACY:
case SD_LEGACY:
esdhc_reset_tuning(mmc);
+ writel(mixctrl, ®s->mixctrl);
+ break;
+ case MMC_HS_400:
+ mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
+ writel(mixctrl, ®s->mixctrl);
+ esdhc_set_strobe_dll(mmc);
break;
case MMC_HS:
case MMC_HS_52:
#endif
if (fdt_get_property(fdt, node, "no-1-8-v", NULL))
- priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200);
+ priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_HS400);
/*
* TODO: