#define mmc_reg_out(addr, mask, val)\
writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
+#define INT_EN_MASK (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)
+
int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
int wp_gpio);
#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);
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;
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;
#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);