Commit ae83e255 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/rmk/linux-2.6-mmc

* master.kernel.org:/home/rmk/linux-2.6-mmc:
  [ARM] 3531/1: i.MX/MX1 SD/MMC ensure, that clock are stopped before new command and cleanups
parents 890f7429 2c171bf1
...@@ -310,7 +310,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) ...@@ -310,7 +310,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
} }
else else
data->bytes_xfered = data->bytes_xfered =
(data->blocks * (1 << data->blksz_bits)) - (data->blocks * data->blksz) -
host->pio.len; host->pio.len;
} }
...@@ -575,7 +575,7 @@ static int ...@@ -575,7 +575,7 @@ static int
au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
{ {
int datalen = data->blocks * (1 << data->blksz_bits); int datalen = data->blocks * data->blksz;
if (dma != 0) if (dma != 0)
host->flags |= HOST_F_DMA; host->flags |= HOST_F_DMA;
...@@ -596,7 +596,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) ...@@ -596,7 +596,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
if (host->dma.len == 0) if (host->dma.len == 0)
return MMC_ERR_TIMEOUT; return MMC_ERR_TIMEOUT;
au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host)); au_writel(data->blksz - 1, HOST_BLKSIZE(host));
if (host->flags & HOST_F_DMA) { if (host->flags & HOST_F_DMA) {
int i; int i;
......
...@@ -218,8 +218,10 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, ...@@ -218,8 +218,10 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host,
if(!loops) if(!loops)
return 0; return 0;
dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n", /* The busy-wait is expected there for clock <8MHz due to SDHC hardware flaws */
loops, where, *pstat, stat_mask); if(!(stat_mask & STATUS_END_CMD_RESP) || (host->mmc->ios.clock>=8000000))
dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n",
loops, where, *pstat, stat_mask);
return loops; return loops;
} }
...@@ -333,6 +335,9 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, ...@@ -333,6 +335,9 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd,
WARN_ON(host->cmd != NULL); WARN_ON(host->cmd != NULL);
host->cmd = cmd; host->cmd = cmd;
/* Ensure, that clock are stopped else command programming and start fails */
imxmci_stop_clock(host);
if (cmd->flags & MMC_RSP_BUSY) if (cmd->flags & MMC_RSP_BUSY)
cmdat |= CMD_DAT_CONT_BUSY; cmdat |= CMD_DAT_CONT_BUSY;
...@@ -553,7 +558,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) ...@@ -553,7 +558,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
int trans_done = 0; int trans_done = 0;
unsigned int stat = *pstat; unsigned int stat = *pstat;
if(host->actual_bus_width == MMC_BUS_WIDTH_4) if(host->actual_bus_width != MMC_BUS_WIDTH_4)
burst_len = 16; burst_len = 16;
else else
burst_len = 64; burst_len = 64;
...@@ -591,8 +596,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) ...@@ -591,8 +596,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
stat = MMC_STATUS; stat = MMC_STATUS;
/* Flush extra bytes from FIFO */ /* Flush extra bytes from FIFO */
while(flush_len >= 2){ while(flush_len && !(stat & STATUS_DATA_TRANS_DONE)){
flush_len -= 2;
i = MMC_BUFFER_ACCESS; i = MMC_BUFFER_ACCESS;
stat = MMC_STATUS; stat = MMC_STATUS;
stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */ stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */
...@@ -746,10 +750,6 @@ static void imxmci_tasklet_fnc(unsigned long data) ...@@ -746,10 +750,6 @@ static void imxmci_tasklet_fnc(unsigned long data)
data_dir_mask = STATUS_DATA_TRANS_DONE; data_dir_mask = STATUS_DATA_TRANS_DONE;
} }
imxmci_busy_wait_for_status(host, &stat,
data_dir_mask,
50, "imxmci_tasklet_fnc data");
if(stat & data_dir_mask) { if(stat & data_dir_mask) {
clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events);
imxmci_data_done(host, stat); imxmci_data_done(host, stat);
...@@ -865,7 +865,11 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -865,7 +865,11 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
imxmci_stop_clock(host); imxmci_stop_clock(host);
MMC_CLK_RATE = (prescaler<<3) | clk; MMC_CLK_RATE = (prescaler<<3) | clk;
imxmci_start_clock(host); /*
* Under my understanding, clock should not be started there, because it would
* initiate SDHC sequencer and send last or random command into card
*/
/*imxmci_start_clock(host);*/
dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE); dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE);
} else { } else {
......
...@@ -951,6 +951,7 @@ static void mmc_read_scrs(struct mmc_host *host) ...@@ -951,6 +951,7 @@ static void mmc_read_scrs(struct mmc_host *host)
data.timeout_ns = card->csd.tacc_ns * 10; data.timeout_ns = card->csd.tacc_ns * 10;
data.timeout_clks = card->csd.tacc_clks * 10; data.timeout_clks = card->csd.tacc_clks * 10;
data.blksz_bits = 3; data.blksz_bits = 3;
data.blksz = 1 << 3;
data.blocks = 1; data.blocks = 1;
data.flags = MMC_DATA_READ; data.flags = MMC_DATA_READ;
data.sg = &sg; data.sg = &sg;
......
...@@ -175,6 +175,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ...@@ -175,6 +175,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.data.timeout_ns = card->csd.tacc_ns * 10; brq.data.timeout_ns = card->csd.tacc_ns * 10;
brq.data.timeout_clks = card->csd.tacc_clks * 10; brq.data.timeout_clks = card->csd.tacc_clks * 10;
brq.data.blksz_bits = md->block_bits; brq.data.blksz_bits = md->block_bits;
brq.data.blksz = 1 << md->block_bits;
brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
brq.stop.opcode = MMC_STOP_TRANSMISSION; brq.stop.opcode = MMC_STOP_TRANSMISSION;
brq.stop.arg = 0; brq.stop.arg = 0;
......
...@@ -119,7 +119,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) ...@@ -119,7 +119,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
nob = 0xffff; nob = 0xffff;
writel(nob, host->base + MMC_NOB); writel(nob, host->base + MMC_NOB);
writel(1 << data->blksz_bits, host->base + MMC_BLKLEN); writel(data->blksz, host->base + MMC_BLKLEN);
clks = (unsigned long long)data->timeout_ns * CLOCKRATE; clks = (unsigned long long)data->timeout_ns * CLOCKRATE;
do_div(clks, 1000000000UL); do_div(clks, 1000000000UL);
...@@ -283,7 +283,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) ...@@ -283,7 +283,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
* data blocks as being in error. * data blocks as being in error.
*/ */
if (data->error == MMC_ERR_NONE) if (data->error == MMC_ERR_NONE)
data->bytes_xfered = data->blocks << data->blksz_bits; data->bytes_xfered = data->blocks * data->blksz;
else else
data->bytes_xfered = 0; data->bytes_xfered = 0;
......
...@@ -662,14 +662,14 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) ...@@ -662,14 +662,14 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
unsigned long dmaflags; unsigned long dmaflags;
DBGF("blksz %04x blks %04x flags %08x\n", DBGF("blksz %04x blks %04x flags %08x\n",
1 << data->blksz_bits, data->blocks, data->flags); data->blksz, data->blocks, data->flags);
DBGF("tsac %d ms nsac %d clk\n", DBGF("tsac %d ms nsac %d clk\n",
data->timeout_ns / 1000000, data->timeout_clks); data->timeout_ns / 1000000, data->timeout_clks);
/* /*
* Calculate size. * Calculate size.
*/ */
host->size = data->blocks << data->blksz_bits; host->size = data->blocks * data->blksz;
/* /*
* Check timeout values for overflow. * Check timeout values for overflow.
...@@ -696,12 +696,12 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) ...@@ -696,12 +696,12 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
* Two bytes are needed for each data line. * Two bytes are needed for each data line.
*/ */
if (host->bus_width == MMC_BUS_WIDTH_1) { if (host->bus_width == MMC_BUS_WIDTH_1) {
blksize = (1 << data->blksz_bits) + 2; blksize = data->blksz + 2;
wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0);
wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
} else if (host->bus_width == MMC_BUS_WIDTH_4) { } else if (host->bus_width == MMC_BUS_WIDTH_4) {
blksize = (1 << data->blksz_bits) + 2 * 4; blksize = data->blksz + 2 * 4;
wbsd_write_index(host, WBSD_IDX_PBSMSB, wbsd_write_index(host, WBSD_IDX_PBSMSB,
((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH); ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH);
......
...@@ -69,6 +69,7 @@ struct mmc_data { ...@@ -69,6 +69,7 @@ struct mmc_data {
unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
unsigned int timeout_clks; /* data timeout (in clocks) */ unsigned int timeout_clks; /* data timeout (in clocks) */
unsigned int blksz_bits; /* data block size */ unsigned int blksz_bits; /* data block size */
unsigned int blksz; /* data block size */
unsigned int blocks; /* number of blocks */ unsigned int blocks; /* number of blocks */
unsigned int error; /* data error */ unsigned int error; /* data error */
unsigned int flags; unsigned int flags;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment