static int rk29_sdmmc_reset_fifo(struct rk29_sdmmc *host)
{
int tmo = RK29_SDMMC_TMO_COUNT;
- if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_MC_BUSY|SDMMC_STAUTS_DATA_BUSY)))
+ int retry = 1000;
+ if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_MC_BUSY|SDMMC_STAUTS_DATA_BUSY)) &&
+ (rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_EMPTY))
return 0;
-
+retry:
rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | SDMMC_CTRL_FIFO_RESET);
while (--tmo && rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_FIFO_RESET);
if(tmo > 0) {
- rk29_sdmmc_set_mrq_status(host, MRQ_RESET_CTRL_DONE);
+ if(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_MC_BUSY|SDMMC_STAUTS_DATA_BUSY)){
+ udelay(1);
+ if(retry <= 0){
+ dev_dbg(host->dev, "%s error,retry = %d\n", __func__,retry);
+ return -1;
+ }
+ retry--;
+ goto retry;
+ }
return 0;
}
else {
- rk29_sdmmc_set_mrq_status(host, MRQ_RESET_CTRL_ERR);
dev_err(host->dev, "%s error\n", __func__);
return -1;
}
static int rk29_sdmmc_reset_ctrl(struct rk29_sdmmc *host)
{
int tmo = RK29_SDMMC_TMO_COUNT;
+ /*
if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_MC_BUSY|SDMMC_STAUTS_DATA_BUSY)))
return 0;
-
+ */
rk29_sdmmc_write(host->regs, SDMMC_CTRL, (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET));
while (--tmo && rk29_sdmmc_read(host->regs, SDMMC_CTRL) & (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET));
rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | SDMMC_CTRL_INT_ENABLE);
~(SDMMC_INT_CMD_DONE | SDMMC_INT_DTO | RK29_SDMMC_ERROR_FLAGS));
if(mrq->stop && !rk29_sdmmc_test_mrq_status(host, MRQ_STOP_START_DONE))
send_stop_cmd(host);
- if(mrq->cmd->opcode == 17 && (host->data_intsts & SDMMC_INT_SBE)){
- rk29_sdmmc_write(host->regs, SDMMC_CMD, SDMMC_CMD_STOP | SDMMC_CMD_START);
+ if(mrq->cmd->opcode == 17|| mrq->cmd->opcode == 51){
+ rk29_sdmmc_write(host->regs, SDMMC_CMD, 12|SDMMC_CMD_STOP | SDMMC_CMD_START);
while (--tmo && rk29_sdmmc_read(host->regs, SDMMC_CMD) & SDMMC_CMD_START);
}
if(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_FULL ){
rk29_sdmmc_read(host->regs, SDMMC_DATA);
rk29_sdmmc_read(host->regs, SDMMC_DATA);
}
- if(mrq->data && mrq->data->error)
+ //if(mrq->data && mrq->data->error)
rk29_sdmmc_reset_fifo(host);
host->mrq = NULL;
else
clock = (host->bus_hz / host->div) >> 1;
timeout = ns_to_clocks(clock, data->timeout_ns) + data->timeout_clks;
- //rk29_sdmmc_write(host->regs, SDMMC_TMOUT, 0xffffffff);
- rk29_sdmmc_write(host->regs, SDMMC_TMOUT, (timeout << 8) | (70));
+ rk29_sdmmc_write(host->regs, SDMMC_TMOUT, 0xffffffff);
+ //rk29_sdmmc_write(host->regs, SDMMC_TMOUT, (timeout << 8) | (70));
}
static u32 rk29_sdmmc_prepare_command(struct mmc_host *mmc,
struct mmc_command *cmd)
host->is_init = 0;
cmdflags |= SDMMC_CMD_INIT;
}
- if(cmd->opcode == 0/* &&
- ((rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_MC_BUSY)||
- (rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_DATA_BUSY))*/)
- cmdflags |= SDMMC_CMD_STOP;
+
if (mrq->data) {
rk29_sdmmc_set_mrq_status(host, MRQ_HAS_DATA);
ret = rk29_sdmmc_submit_data(host, mrq->data);
}
dev_dbg(host->dev,"start cmd:%d ARGR=0x%08x CMDR=0x%08x\n",
cmd->opcode, cmd->arg, cmdflags);
-
+
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS, ~SDMMC_INT_SDIO);
rk29_sdmmc_write(host->regs, SDMMC_INTMASK,
rk29_sdmmc_read(host->regs, SDMMC_INTMASK) |
if (mrq->stop) {
rk29_sdmmc_set_mrq_status(host, MRQ_HAS_STOP);
host->stop_cmdr = rk29_sdmmc_prepare_command(host->mmc, mrq->stop);
+ if(mrq->cmd->opcode == 25)
+ host->stop_cmdr |= SDMMC_CMD_DAT_WR;
}
spin_unlock(&host->lock);
return 0;
{
int timeout;
struct rk29_sdmmc *host = mmc_priv(mmc);
-
+ if(!mrq)
+ dev_info(host->dev, "mrq = NULL!!!!!\n");
if(host->mrq)
rk29_sdmmc_show_info(host);
WARN_ON(host->mrq);
}
rk29_sdmmc_request_end(host);
}
- //rk29_sdmmc_reset_ctrl(host);
+ rk29_sdmmc_reset_fifo(host);
spin_unlock(&host->lock);
mmc_detect_change(host->mmc, 0);
}