((mrq->cmd->arg == MMC_DISCARD_ARG) ||
(mrq->cmd->arg == MMC_TRIM_ARG))) ?
(*timeout = 10000) : (*timeout = 25000);
+ else if (mrq->cmd->opcode == MMC_SWITCH)
+ *timeout = mrq->cmd->cmd_timeout_ms;
else
*timeout = 500;
msecs_to_jiffies(timeout))) {
cmd = mrq->cmd;
cmd->error = -ETIMEDOUT;
- host->ops->post_tmo(host);
- context_info->is_done_rcv = true;
dev_err(mmc_dev(host),
"req failed (CMD%u): error = %d, timeout = %dms\n",
cmd->opcode, cmd->error, timeout);
+ host->ops->post_tmo(host);
+ context_info->is_done_rcv = true;
}
spin_lock_irqsave(&context_info->lock, flags);
msecs_to_jiffies(timeout))) {
cmd = mrq->cmd;
cmd->error = -ETIMEDOUT;
- host->ops->post_tmo(host);
-
dev_err(mmc_dev(host),
"req failed (CMD%u): error = %d, timeout = %dms\n",
cmd->opcode, cmd->error, timeout);
- if (!cmd->data)
- break;
+ host->ops->post_tmo(host);
}
cmd = mrq->cmd;
rockchip_compat[idx].compatible)) {
priv->ctrl_type = rockchip_compat[idx].ctrl_type;
host->cid = priv->ctrl_type;
- host->grf = syscon_find(host->dev->of_node,
- "rockchip,grf");
+ if (priv->ctrl_type == DW_MCI_TYPE_RK3368) {
+ host->grf = syscon_regmap_lookup_by_phandle(
+ host->dev->of_node, "rockchip,grf");
+ if (IS_ERR(host->grf)) {
+ pr_err("No rockchip,grf phandle specified");
+ return PTR_ERR(host->grf);
+ }
+ host->cru = syscon_regmap_lookup_by_phandle(
+ host->dev->of_node, "rockchip,cru");
+ if (IS_ERR(host->cru)) {
+ pr_err("No rockchip,cru phandle specified");
+ return PTR_ERR(host->cru);
+ }
+ }
}
}
struct dw_mci_slot *slot = mmc_priv(mmc);
struct dw_mci *host = slot->host;
struct mmc_data *data;
- u32 ret, i, regs, cmd_flags;
+ u32 i, regs, cmd_flags;
u32 sdio_int;
unsigned long timeout = 0;
- bool ret_timeout = true;
- u32 opcode;
+ bool ret_timeout = true, is_retry = false;
+ u32 opcode, offset;
+ offset = host->cru_reset_offset;
opcode = host->mrq->cmd->opcode;
host->cur_slot->mrq = NULL;
host->mrq = NULL;
if ((opcode == MMC_SEND_TUNING_BLOCK_HS200) ||
(opcode == MMC_SEND_TUNING_BLOCK))
- return;
+ return;
printk("[%s] -- Timeout recovery procedure start --\n",
mmc_hostname(host->mmc));
+ /* unmask irq */
+ mci_writel(host, INTMASK, 0x0);
+
+retry_stop:
+ /* send stop cmd */
mci_writel(host, CMDARG, 0);
wmb();
cmd_flags = SDMMC_CMD_STOP | SDMMC_CMD_RESP_CRC |
mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START);
wmb();
- timeout = jiffies + msecs_to_jiffies(500);
+ timeout = jiffies + msecs_to_jiffies(10);
while(ret_timeout) {
ret_timeout = time_before(jiffies, timeout);
break;
}
- if (false == ret_timeout)
+ if (false == ret_timeout) {
MMC_DBG_ERR_FUNC(host->mmc, "stop recovery failed![%s]",
mmc_hostname(host->mmc));
-
- if (!dw_mci_ctrl_all_reset(host)) {
- ret = -ENODEV;
- return ;
+ if (host->cid == DW_MCI_TYPE_RK3368) {
+ /* pd_peri mmc AHB bus software reset request */
+ regmap_write(host->cru, host->cru_regsbase,
+ (0x1<<offset)<<16 | (0x1 << offset));
+ mdelay(1);
+ regmap_write(host->cru, host->cru_regsbase,
+ (0x1<<offset)<<16 | (0x0 << offset));
+ } else {
+ /* pd_peri mmc AHB bus software reset request */
+ cru_writel(((0x1<<offset)<<16) | (0x1 << offset),
+ host->cru_regsbase);
+ mdelay(1);
+ cru_writel(((0x1<<offset)<<16) | (0x0 << offset),
+ host->cru_regsbase);
+ }
+ } else {
+ if (!dw_mci_ctrl_all_reset(host))
+ return;
+ if (is_retry == true)
+ goto recovery_end;
}
#ifdef CONFIG_MMC_DW_IDMAC
#endif
/*
- * Restore the initial value at FIFOTH register
- * And Invalidate the prev_blksz with zero
- */
+ * Restore the initial value at FIFOTH register
+ * And Invalidate the prev_blksz with zero
+ */
mci_writel(host, FIFOTH, host->fifoth_val);
host->prev_blksz = 0;
mci_writel(host, TMOUT, 0xFFFFFFFF);
mci_writel(host, RINTSTS, 0xFFFFFFFF);
- regs = SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | SDMMC_INT_TXDR
- | SDMMC_INT_RXDR | SDMMC_INT_VSI | DW_MCI_ERROR_FLAGS;
+ regs = SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
+ SDMMC_INT_TXDR | SDMMC_INT_RXDR | SDMMC_INT_VSI |
+ DW_MCI_ERROR_FLAGS;
if (!(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO))
regs |= SDMMC_INT_CD;
}
}
mci_writel(host, RINTSTS, 0xFFFFFFFF);
+ if (ret_timeout == false) {
+ ret_timeout = true;
+ is_retry = true;
+ goto retry_stop;
+ }
+recovery_end:
printk("[%s] -- Timeout recovery procedure finished --\n",
mmc_hostname(host->mmc));
}
if (of_get_property(np, "assume_removable", NULL))
mmc_assume_removable = 0;
+ if (!of_property_read_u32(np, "cru_regsbase", &host->cru_regsbase)) {
+ printk("dw cru_regsbase addr 0x%03x.\n", host->cru_regsbase);
+ } else {
+ pr_err("dw cru_regsbase addr is missing!\n");
+ return ERR_PTR(-1);
+ }
+
+ if (!of_property_read_u32(np, "cru_reset_offset", &host->cru_reset_offset)) {
+ printk("dw cru_reset_offset val %d.\n", host->cru_reset_offset);
+ } else {
+ pr_err("dw cru_reset_offset val is missing!\n");
+ return ERR_PTR(-1);
+ }
+
return pdata;
}