From 340ff20871ab9360b23fa5870706cb78c7ea80be Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Mon, 10 Jan 2011 18:31:09 +0800 Subject: [PATCH] mmc: rk29: clean up & use udelay instead of mdelay before use 18% __delay while play video, after only 1.6%. --- drivers/mmc/host/rk29_sdmmc.c | 105 ++++++++++++---------------------- 1 file changed, 36 insertions(+), 69 deletions(-) diff --git a/drivers/mmc/host/rk29_sdmmc.c b/drivers/mmc/host/rk29_sdmmc.c index 8c5fb1656f79..4ab9a1f603d0 100755 --- a/drivers/mmc/host/rk29_sdmmc.c +++ b/drivers/mmc/host/rk29_sdmmc.c @@ -353,35 +353,43 @@ static void rk29_sdmmc_start_command(struct rk29_sdmmc *host, } } -static void send_stop_cmd(struct rk29_sdmmc *host, struct mmc_data *data) +static void rk29_sdmmc_reset_fifo(struct rk29_sdmmc *host) { - int time_out=100, time_out2=3; unsigned long flags; - - - while(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_DATA_BUSY)) { - mdelay(5); - time_out --; - if(!time_out){ - time_out =60; - local_irq_save(flags); - rk29_sdmmc_write( host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET )); - /* wait till resets clear */ - while (rk29_sdmmc_read(host->regs, SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET)); - local_irq_restore(flags); + + local_irq_save(flags); + rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | SDMMC_CTRL_FIFO_RESET); + /* wait till resets clear */ + while (rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_FIFO_RESET); + local_irq_restore(flags); +} + +static int rk29_sdmmc_wait_unbusy(struct rk29_sdmmc *host) +{ + const int time_out_us = 500000; + int time_out = time_out_us, time_out2 = 3; + + while (rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_DATA_BUSY) { + udelay(1); + time_out--; + if (!time_out) { + time_out = time_out_us; + rk29_sdmmc_reset_fifo(host); time_out2--; - if(!time_out2) + if (!time_out2) break; - } } - + + return time_out_us - time_out; +} + +static void send_stop_cmd(struct rk29_sdmmc *host, struct mmc_data *data) +{ + rk29_sdmmc_wait_unbusy(host); + if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_EMPTY)) { - local_irq_save(flags); - rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET )); - /* wait till resets clear */ - while (readl(host->regs + SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET)); - local_irq_restore(flags); + rk29_sdmmc_reset_fifo(host); } rk29_sdmmc_start_command(host, data->stop, host->stop_cmdr); } @@ -554,34 +562,13 @@ static void rk29_sdmmc_start_request(struct rk29_sdmmc *host) struct mmc_command *cmd; struct mmc_data *data; u32 cmdflags; - int time_out=100, time_out2=3; - unsigned long flags; mrq = host->mrq; - - while(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_DATA_BUSY)) { - mdelay(5); - time_out --; - if(!time_out){ - time_out =60; - local_irq_save(flags); - rk29_sdmmc_write( host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET )); - /* wait till resets clear */ - while (rk29_sdmmc_read(host->regs, SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET)); - local_irq_restore(flags); - time_out2--; - if(!time_out2) - break; - - } - } + + rk29_sdmmc_wait_unbusy(host); if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_EMPTY)) { - local_irq_save(flags); - rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET )); - /* wait till resets clear */ - while (readl(host->regs + SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET)); - local_irq_restore(flags); + rk29_sdmmc_reset_fifo(host); } /* Slot specific timing and width adjustment */ rk29_sdmmc_setup_bus(host); @@ -726,35 +713,15 @@ static void rk29_sdmmc_request_end(struct rk29_sdmmc *host, struct mmc_request * __acquires(&host->lock) { struct mmc_host *prev_mmc = host->mmc; - unsigned long flags; - int time_out=100, time_out2=3; WARN_ON(host->cmd || host->data); host->curr_mrq = NULL; host->mrq = NULL; - while(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_DATA_BUSY)) { - mdelay(5); - time_out --; - if(!time_out){ - time_out =60; - local_irq_save(flags); - rk29_sdmmc_write( host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET )); - /* wait till resets clear */ - while (rk29_sdmmc_read(host->regs, SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET)); - local_irq_restore(flags); - time_out2--; - if(!time_out2) - break; - } - } - + rk29_sdmmc_wait_unbusy(host); + if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_EMPTY)) { - local_irq_save(flags); - rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET )); - /* wait till resets clear */ - while (readl(host->regs + SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET)); - local_irq_restore(flags); + rk29_sdmmc_reset_fifo(host); } if (!list_empty(&host->queue)) { host = list_entry(host->queue.next, -- 2.34.1