mmc: fsl_esdhc: add compatible for fsl, imx53-esdhc
[oweals/u-boot.git] / drivers / mmc / fsl_esdhc.c
index 03c6743ae89f6e48a6f95a51a13379dbf9845829..2fa61c4259b51ba6fb502d1a96ae39cd020cf204 100644 (file)
@@ -11,6 +11,7 @@
 #include <config.h>
 #include <common.h>
 #include <command.h>
+#include <clk.h>
 #include <errno.h>
 #include <hwconfig.h>
 #include <mmc.h>
@@ -121,6 +122,7 @@ struct esdhc_soc_data {
 struct fsl_esdhc_priv {
        struct fsl_esdhc *esdhc_regs;
        unsigned int sdhc_clk;
+       struct clk per_clk;
        unsigned int clock;
        unsigned int mode;
        unsigned int bus_width;
@@ -257,7 +259,7 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
        int timeout;
        struct fsl_esdhc *regs = priv->esdhc_regs;
 #if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
-       defined(CONFIG_MX8M)
+       defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
        dma_addr_t addr;
 #endif
        uint wml_value;
@@ -271,7 +273,7 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
                esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
 #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
 #if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
-       defined(CONFIG_MX8M)
+       defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
                addr = virt_to_phys((void *)(data->dest));
                if (upper_32_bits(addr))
                        printf("Error found for upper 32 bits\n");
@@ -301,7 +303,7 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
                                        wml_value << 16);
 #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
 #if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
-       defined(CONFIG_MX8M)
+       defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
                addr = virt_to_phys((void *)(data->src));
                if (upper_32_bits(addr))
                        printf("Error found for upper 32 bits\n");
@@ -367,7 +369,7 @@ static void check_and_invalidate_dcache_range
        unsigned size = roundup(ARCH_DMA_MINALIGN,
                                data->blocks*data->blocksize);
 #if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
-       defined(CONFIG_MX8M)
+       defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
        dma_addr_t addr;
 
        addr = virt_to_phys((void *)(data->dest));
@@ -394,6 +396,7 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
        uint    irqstat;
        u32     flags = IRQSTAT_CC | IRQSTAT_CTOE;
        struct fsl_esdhc *regs = priv->esdhc_regs;
+       unsigned long start;
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
        if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
@@ -451,8 +454,13 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
                flags = IRQSTAT_BRR;
 
        /* Wait for the command to complete */
-       while (!(esdhc_read32(&regs->irqstat) & flags))
-               ;
+       start = get_timer(0);
+       while (!(esdhc_read32(&regs->irqstat) & flags)) {
+               if (get_timer(start) > 1000) {
+                       err = -ETIMEDOUT;
+                       goto out;
+               }
+       }
 
        irqstat = esdhc_read32(&regs->irqstat);
 
@@ -1496,10 +1504,26 @@ static int fsl_esdhc_probe(struct udevice *dev)
 
        init_clk_usdhc(dev->seq);
 
-       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;
+       if (IS_ENABLED(CONFIG_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;
+               }
        }
 
        ret = fsl_esdhc_init(priv, plat);
@@ -1521,7 +1545,6 @@ static int fsl_esdhc_get_cd(struct udevice *dev)
 {
        struct fsl_esdhc_priv *priv = dev_get_priv(dev);
 
-       return true;
        return esdhc_getcd_common(priv);
 }
 
@@ -1561,6 +1584,7 @@ static struct esdhc_soc_data usdhc_imx7d_data = {
 };
 
 static const struct udevice_id fsl_esdhc_ids[] = {
+       { .compatible = "fsl,imx53-esdhc", },
        { .compatible = "fsl,imx6ul-usdhc", },
        { .compatible = "fsl,imx6sx-usdhc", },
        { .compatible = "fsl,imx6sl-usdhc", },