mmc: Merge SD_LEGACY and MMC_LEGACY bus modes
[oweals/u-boot.git] / drivers / mmc / fsl_esdhc_imx.c
index f7b754bd9d37f520e92ecfcbb59c92a6d1eeb583..6bca2a9c829ed26311bb17eba6ea6fa88e243a8e 100644 (file)
@@ -19,6 +19,8 @@
 #include <hwconfig.h>
 #include <mmc.h>
 #include <part.h>
+#include <dm/device_compat.h>
+#include <linux/err.h>
 #include <power/regulator.h>
 #include <malloc.h>
 #include <fsl_esdhc_imx.h>
@@ -78,7 +80,7 @@ struct fsl_esdhc {
        uint    vendorspec;
        uint    mmcboot;
        uint    vendorspec2;
-       uint    tuning_ctrl;    /* on i.MX6/7/8 */
+       uint    tuning_ctrl;    /* on i.MX6/7/8/RT */
        char    reserved5[44];
        uint    hostver;        /* Host controller version register */
        char    reserved6[4];   /* reserved */
@@ -115,6 +117,7 @@ struct esdhc_soc_data {
  * Following is used when Driver Model is enabled for MMC
  * @dev: pointer for the device
  * @non_removable: 0: removable; 1: non-removable
+ * @broken_cd: 0: use GPIO for card detect; 1: Do not use GPIO for card detect
  * @wp_enable: 1: enable checking wp; 0: no check
  * @vs18_enable: 1: use 1.8V voltage; 0: use 3.3V
  * @flags: ESDHC_FLAG_xx in include/fsl_esdhc_imx.h
@@ -138,6 +141,7 @@ struct fsl_esdhc_priv {
 #endif
        struct udevice *dev;
        int non_removable;
+       int broken_cd;
        int wp_enable;
        int vs18_enable;
        u32 flags;
@@ -659,35 +663,6 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
        priv->clock = clock;
 }
 
-#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
-static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable)
-{
-       struct fsl_esdhc *regs = priv->esdhc_regs;
-       u32 value;
-       u32 time_out;
-
-       value = esdhc_read32(&regs->sysctl);
-
-       if (enable)
-               value |= SYSCTL_CKEN;
-       else
-               value &= ~SYSCTL_CKEN;
-
-       esdhc_write32(&regs->sysctl, value);
-
-       time_out = 20;
-       value = PRSSTAT_SDSTB;
-       while (!(esdhc_read32(&regs->prsstat) & value)) {
-               if (time_out == 0) {
-                       printf("fsl_esdhc: Internal clock never stabilised.\n");
-                       break;
-               }
-               time_out--;
-               mdelay(1);
-       }
-}
-#endif
-
 #ifdef MMC_SUPPORTS_TUNING
 static int esdhc_change_pinstate(struct udevice *dev)
 {
@@ -768,7 +743,6 @@ static int esdhc_set_timing(struct mmc *mmc)
 
        switch (mmc->selected_mode) {
        case MMC_LEGACY:
-       case SD_LEGACY:
                esdhc_reset_tuning(mmc);
                writel(mixctrl, &regs->mixctrl);
                break;
@@ -959,12 +933,6 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
        int ret __maybe_unused;
        u32 clock;
 
-#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
-       /* Select to use peripheral clock */
-       esdhc_clock_control(priv, false);
-       esdhc_setbits32(&regs->scr, ESDHCCTL_PCS);
-       esdhc_clock_control(priv, true);
-#endif
        /* Set the clock speed */
        clock = mmc->clock;
        if (clock < mmc->cfg->f_min)
@@ -1093,6 +1061,9 @@ static int esdhc_getcd_common(struct fsl_esdhc_priv *priv)
 #if CONFIG_IS_ENABLED(DM_MMC)
        if (priv->non_removable)
                return 1;
+
+       if (priv->broken_cd)
+               return 1;
 #if CONFIG_IS_ENABLED(DM_GPIO)
        if (dm_gpio_is_valid(&priv->cd_gpio))
                return dm_gpio_get_value(&priv->cd_gpio);
@@ -1389,13 +1360,8 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd)
        if (esdhc_status_fixup(blob, compat))
                return;
 
-#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
-       do_fixup_by_compat_u32(blob, compat, "peripheral-frequency",
-                              gd->arch.sdhc_clk, 1);
-#else
        do_fixup_by_compat_u32(blob, compat, "clock-frequency",
                               gd->arch.sdhc_clk, 1);
-#endif
 }
 #endif
 
@@ -1451,6 +1417,9 @@ static int fsl_esdhc_probe(struct udevice *dev)
                             ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT);
        priv->strobe_dll_delay_target = val;
 
+       if (dev_read_bool(dev, "broken-cd"))
+               priv->broken_cd = 1;
+
        if (dev_read_bool(dev, "non-removable")) {
                priv->non_removable = 1;
         } else {
@@ -1515,27 +1484,27 @@ static int fsl_esdhc_probe(struct udevice *dev)
 
        init_clk_usdhc(dev->seq);
 
-       if (CONFIG_IS_ENABLED(CLK)) {
-               /* Assigned clock already set clock */
-               ret = clk_get_by_name(dev, "per", &priv->per_clk);
-               if (ret) {
-                       printf("Failed to get per_clk\n");
-                       return ret;
-               }
-               ret = clk_enable(&priv->per_clk);
-               if (ret) {
-                       printf("Failed to enable per_clk\n");
-                       return ret;
-               }
+#if CONFIG_IS_ENABLED(CLK)
+       /* Assigned clock already set clock */
+       ret = clk_get_by_name(dev, "per", &priv->per_clk);
+       if (ret) {
+               printf("Failed to get per_clk\n");
+               return ret;
+       }
+       ret = clk_enable(&priv->per_clk);
+       if (ret) {
+               printf("Failed to enable per_clk\n");
+               return ret;
+       }
 
-               priv->sdhc_clk = clk_get_rate(&priv->per_clk);
-       } else {
-               priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev->seq);
-               if (priv->sdhc_clk <= 0) {
-                       dev_err(dev, "Unable to get clk for %s\n", dev->name);
-                       return -EINVAL;
-               }
+       priv->sdhc_clk = clk_get_rate(&priv->per_clk);
+#else
+       priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev->seq);
+       if (priv->sdhc_clk <= 0) {
+               dev_err(dev, "Unable to get clk for %s\n", dev->name);
+               return -EINVAL;
        }
+#endif
 
        ret = fsl_esdhc_init(priv, plat);
        if (ret) {
@@ -1652,6 +1621,7 @@ static const struct udevice_id fsl_esdhc_ids[] = {
        { .compatible = "fsl,imx8mm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
        { .compatible = "fsl,imx8mn-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
        { .compatible = "fsl,imx8mq-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
+       { .compatible = "fsl,imxrt-usdhc", },
        { .compatible = "fsl,esdhc", },
        { /* sentinel */ }
 };