aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
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