aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-10-03 11:48:16 -0400
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-10-05 14:39:20 -0400
commit945533b538c6c6185afc77ba4a81eeba8f6ef8dd (patch)
tree5bb72f5ac9e50cdaeca19f14c18970acc30acccf /drivers/mmc
parentc06ad2580dca4eb14ca07541d4f00a3b7cbcf12f (diff)
atmel-mci: Don't stop the clock between transfers
Some cards might get upset if we turn off the clock for extended periods of time. So keep the clock running until the mmc core tells us to turn it off. Also, don't reset the controller between each transfer. That was an attempt to work around earlier bugs, and it never really worked very well. Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/atmel-mci.c60
1 files changed, 22 insertions, 38 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index d834e3756aef..14ab28da7fa8 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -279,23 +279,6 @@ err:
279 "failed to initialize debugfs for controller\n"); 279 "failed to initialize debugfs for controller\n");
280} 280}
281 281
282static void atmci_enable(struct atmel_mci *host)
283{
284 clk_enable(host->mck);
285 mci_writel(host, CR, MCI_CR_MCIEN);
286 mci_writel(host, MR, host->mode_reg);
287 mci_writel(host, SDCR, host->sdc_reg);
288}
289
290static void atmci_disable(struct atmel_mci *host)
291{
292 mci_writel(host, CR, MCI_CR_SWRST);
293
294 /* Stall until write is complete, then disable the bus clock */
295 mci_readl(host, SR);
296 clk_disable(host->mck);
297}
298
299static inline unsigned int ns_to_clocks(struct atmel_mci *host, 282static inline unsigned int ns_to_clocks(struct atmel_mci *host,
300 unsigned int ns) 283 unsigned int ns)
301{ 284{
@@ -408,8 +391,6 @@ static void atmci_request_end(struct mmc_host *mmc, struct mmc_request *mrq)
408 WARN_ON(host->cmd || host->data); 391 WARN_ON(host->cmd || host->data);
409 host->mrq = NULL; 392 host->mrq = NULL;
410 393
411 atmci_disable(host);
412
413 mmc_request_done(mmc, mrq); 394 mmc_request_done(mmc, mrq);
414} 395}
415 396
@@ -476,8 +457,6 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
476 host->completed_events = 0; 457 host->completed_events = 0;
477 host->state = STATE_SENDING_CMD; 458 host->state = STATE_SENDING_CMD;
478 459
479 atmci_enable(host);
480
481 /* We don't support multiple blocks of weird lengths. */ 460 /* We don't support multiple blocks of weird lengths. */
482 data = mrq->data; 461 data = mrq->data;
483 if (data) { 462 if (data) {
@@ -520,7 +499,6 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
520 return; 499 return;
521 500
522fail: 501fail:
523 atmci_disable(host);
524 host->mrq = NULL; 502 host->mrq = NULL;
525 mrq->cmd->error = -EINVAL; 503 mrq->cmd->error = -EINVAL;
526 mmc_request_done(mmc, mrq); 504 mmc_request_done(mmc, mrq);
@@ -530,9 +508,21 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
530{ 508{
531 struct atmel_mci *host = mmc_priv(mmc); 509 struct atmel_mci *host = mmc_priv(mmc);
532 510
511 switch (ios->bus_width) {
512 case MMC_BUS_WIDTH_1:
513 host->sdc_reg = 0;
514 break;
515 case MMC_BUS_WIDTH_4:
516 host->sdc_reg = MCI_SDCBUS_4BIT;
517 break;
518 }
519
533 if (ios->clock) { 520 if (ios->clock) {
534 u32 clkdiv; 521 u32 clkdiv;
535 522
523 if (!host->mode_reg)
524 clk_enable(host->mck);
525
536 /* Set clock rate */ 526 /* Set clock rate */
537 clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * ios->clock) - 1; 527 clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * ios->clock) - 1;
538 if (clkdiv > 255) { 528 if (clkdiv > 255) {
@@ -544,26 +534,20 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
544 534
545 host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF 535 host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF
546 | MCI_MR_RDPROOF; 536 | MCI_MR_RDPROOF;
547 }
548 537
549 switch (ios->bus_width) { 538 mci_writel(host, CR, MCI_CR_MCIEN);
550 case MMC_BUS_WIDTH_1: 539 mci_writel(host, MR, host->mode_reg);
551 host->sdc_reg = 0; 540 mci_writel(host, SDCR, host->sdc_reg);
552 break; 541 } else {
553 case MMC_BUS_WIDTH_4: 542 mci_writel(host, CR, MCI_CR_MCIDIS);
554 host->sdc_reg = MCI_SDCBUS_4BIT; 543 if (host->mode_reg) {
555 break; 544 mci_readl(host, MR);
545 clk_disable(host->mck);
546 }
547 host->mode_reg = 0;
556 } 548 }
557 549
558 switch (ios->power_mode) { 550 switch (ios->power_mode) {
559 case MMC_POWER_ON:
560 /* Send init sequence (74 clock cycles) */
561 atmci_enable(host);
562 mci_writel(host, CMDR, MCI_CMDR_SPCMD_INIT);
563 while (!(mci_readl(host, SR) & MCI_CMDRDY))
564 cpu_relax();
565 atmci_disable(host);
566 break;
567 default: 551 default:
568 /* 552 /*
569 * TODO: None of the currently available AVR32-based 553 * TODO: None of the currently available AVR32-based