]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - drivers/mmc/omap_hsmmc.c
mmc: omap_hsmmc: Workaround for errata id i802
[people/ms/u-boot.git] / drivers / mmc / omap_hsmmc.c
index 69a7c2eed4b33ba019537045e0937ca29ba06854..55232103e08af8946e110ea539fabfef310abc85 100644 (file)
@@ -476,6 +476,25 @@ tuning_error:
 #endif
 #endif
 
+static void mmc_enable_irq(struct mmc *mmc, struct mmc_cmd *cmd)
+{
+       struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+       struct hsmmc *mmc_base = priv->base_addr;
+       u32 irq_mask = INT_EN_MASK;
+
+       /*
+        * TODO: Errata i802 indicates only DCRC interrupts can occur during
+        * tuning procedure and DCRC should be disabled. But see occurences
+        * of DEB, CIE, CEB, CCRC interupts during tuning procedure. These
+        * interrupts occur along with BRR, so the data is actually in the
+        * buffer. It has to be debugged why these interrutps occur
+        */
+       if (cmd && mmc_is_tuning_cmd(cmd->cmdidx))
+               irq_mask &= ~(IE_DEB | IE_DCRC | IE_CIE | IE_CEB | IE_CCRC);
+
+       writel(irq_mask, &mmc_base->ie);
+}
+
 static int omap_hsmmc_init_setup(struct mmc *mmc)
 {
        struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
@@ -542,10 +561,7 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
 
        writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);
 
-       writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
-               IE_CEB | IE_CCRC | IE_ADMAE | IE_CTO | IE_BRR | IE_BWR | IE_TC |
-               IE_CC, &mmc_base->ie);
-
+       mmc_enable_irq(mmc, NULL);
        mmc_init_stream(mmc_base);
 
        return 0;
@@ -718,10 +734,8 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
                        struct mmc_data *data)
 {
        struct omap_hsmmc_data *priv = dev_get_priv(dev);
-#ifndef CONFIG_OMAP34XX
        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
        struct mmc *mmc = upriv->mmc;
-#endif
 #endif
        struct hsmmc *mmc_base;
        unsigned int flags, mmc_stat;
@@ -810,6 +824,8 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
 #endif
        }
 
+       mmc_enable_irq(mmc, cmd);
+
        writel(cmd->cmdarg, &mmc_base->arg);
        udelay(20);             /* To fix "No status update" error on eMMC */
        writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);