summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/omap_hsmmc.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 69a7c2eed4..55232103e0 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -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,11 +734,9 @@ 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;
ulong start;
@@ -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);