#define SDMMC_DATA_TIMEOUT_EMMC 2500
#define SDMMC_CMD_RTO_MAX_HOLD 200
-//#define SDMMC_WAIT_FOR_UNBUSY 2500
+#define SDMMC_WAIT_FOR_UNBUSY 2500
#ifdef CONFIG_MMC_DW_IDMAC
#define IDMAC_INT_CLR (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
struct mmc_command *cmd;
enum dw_mci_state state;
enum dw_mci_state prev_state;
- u32 status, ctrl;
+ u32 status, ctrl, cmd_flags;
spin_lock(&host->lock);
#if 1
if (data->stop)
send_stop_cmd(host, data);
+ else{
+ /*single block read/write, send stop cmd manually to prevent host controller halt*/
+ printk("%s status 1 0x%08x [%s]\n",__func__,mci_readl(host, STATUS),mmc_hostname(host->mmc));
+ mci_writel(host, CMDARG, 0);
+ wmb();
+ cmd_flags = SDMMC_CMD_STOP |SDMMC_CMD_RESP_CRC|SDMMC_CMD_RESP_EXP|MMC_STOP_TRANSMISSION;
+ if(host->mmc->hold_reg_flag)
+ cmd_flags |= SDMMC_CMD_USE_HOLD_REG;
+ // mci_writel(host, CMD, SDMMC_CMD_USE_HOLD_REG |SDMMC_CMD_STOP |SDMMC_CMD_RESP_CRC|SDMMC_CMD_RESP_EXP| SDMMC_CMD_START|0x0c);
+ mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START);
+ wmb();
+ while(1){
+ if(!(mci_readl(host, CMD)&SDMMC_CMD_START))
+ break;
+ }
+ }
#else
send_stop_abort(host, data);
#endif
if (!test_and_clear_bit(EVENT_XFER_COMPLETE,
&host->pending_events))
break;
- MMC_DBG_INFO_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: STATE_SENDING_DATA, wait for EVENT_DATA_COMPLETE. [%s]",\
- prev_state,state,mmc_hostname(host->mmc));
+ MMC_DBG_INFO_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: STATE_SENDING_DATA, wait for EVENT_DATA_COMPLETE. [%s]",\
+ prev_state,state,mmc_hostname(host->mmc));
set_bit(EVENT_XFER_COMPLETE, &host->completed_events);
prev_state = state = STATE_DATA_BUSY;
break;
dw_mci_deal_data_end(host, host->mrq);
- MMC_DBG_INFO_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: STATE_DATA_BUSY, after EVENT_DATA_COMPLETE. [%s]", \
- prev_state,state,mmc_hostname(host->mmc));
+ MMC_DBG_INFO_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: STATE_DATA_BUSY, after EVENT_DATA_COMPLETE. [%s]", \
+ prev_state,state,mmc_hostname(host->mmc));
host->data = NULL;
set_bit(EVENT_DATA_COMPLETE, &host->completed_events);
if (status & DW_MCI_DATA_ERROR_FLAGS) {
if((SDMMC_CTYPE_1BIT != slot->ctype)&&(MMC_SEND_EXT_CSD == host->mrq->cmd->opcode))
- MMC_DBG_ERR_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: DW_MCI_DATA_ERROR_FLAGS,datastatus=0x%x [%s]",\
+ MMC_DBG_ERR_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: DW_MCI_DATA_ERROR_FLAGS,datastatus=0x%x [%s]",\
prev_state,state, status, mmc_hostname(host->mmc));
if (status & SDMMC_INT_DRTO) {
}
if (!data->stop) {
- MMC_DBG_CMD_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: no stop and no dataerr, exit. [%s]", \
- prev_state,state,mmc_hostname(host->mmc));
+ MMC_DBG_CMD_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: no stop and no dataerr, exit. [%s]", \
+ prev_state,state,mmc_hostname(host->mmc));
dw_mci_request_end(host, host->mrq);
goto unlock;
}
int i;
pending = mci_readl(host, MINTSTS); /* read-only mask reg */
-
+ //if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
+ // printk("%s pending: 0x%08x\n",__func__,pending);
/*
* DTO fix - version 2.10a and below, and only if internal DMA
* is configured.
host->cmd_status = pending;
smp_wmb();
MMC_DBG_INFO_FUNC(host->mmc,"Line%d..%s cmd_status INT=0x%x,[%s]",
- __LINE__, __FUNCTION__,host->cmd_status,mmc_hostname(host->mmc));
+ __LINE__, __FUNCTION__,host->cmd_status,mmc_hostname(host->mmc));
set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
}
set_bit(EVENT_DATA_ERROR, &host->pending_events);
MMC_DBG_INFO_FUNC(host->mmc,"Line%d..%s data_status INT=0x%x,[%s]",
- __LINE__, __FUNCTION__,host->data_status,mmc_hostname(host->mmc));
+ __LINE__, __FUNCTION__,host->data_status,mmc_hostname(host->mmc));
tasklet_schedule(&host->tasklet);
}
}
if (pending & SDMMC_INT_VSI) {
- MMC_DBG_SW_VOL_FUNC(host->mmc, "SDMMC_INT_VSI, INT-pending=0x%x. [%s]",pending,mmc_hostname(host->mmc));
+ MMC_DBG_SW_VOL_FUNC(host->mmc, "SDMMC_INT_VSI, INT-pending=0x%x. [%s]",pending,mmc_hostname(host->mmc));
mci_writel(host, RINTSTS, SDMMC_INT_VSI);
dw_mci_cmd_interrupt(host, pending);
}
if (pending & SDMMC_INT_CMD_DONE) {
- MMC_DBG_CMD_FUNC(host->mmc, "SDMMC_INT_CMD_DONE, INT-pending=0x%x. [%s]",pending,mmc_hostname(host->mmc));
+ MMC_DBG_CMD_FUNC(host->mmc, "SDMMC_INT_CMD_DONE, INT-pending=0x%x. [%s]",pending,mmc_hostname(host->mmc));
mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE);
dw_mci_cmd_interrupt(host, pending);
}
rk_send_wakeup_key();//wake up system
queue_work(host->card_workqueue, &host->card_work);
}
+
+ if (pending & SDMMC_INT_HLE) {
+ mci_writel(host, RINTSTS, SDMMC_INT_HLE);
+ MMC_DBG_CMD_FUNC(host->mmc, "SDMMC_INT_HLE INT-pending=0x%x. [%s]\n",pending,mmc_hostname(host->mmc));
+
+ }
/* Handle SDIO Interrupts */
for (i = 0; i < host->num_slots; i++) {