diff options
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r-- | drivers/mmc/core/mmc.c | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 6909a54c39be..995261f7fd70 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -258,6 +258,21 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
258 | } | 258 | } |
259 | 259 | ||
260 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { | 260 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { |
261 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | | ||
262 | EXT_CSD_CARD_TYPE_26: | ||
263 | card->ext_csd.hs_max_dtr = 52000000; | ||
264 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52; | ||
265 | break; | ||
266 | case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 | | ||
267 | EXT_CSD_CARD_TYPE_26: | ||
268 | card->ext_csd.hs_max_dtr = 52000000; | ||
269 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V; | ||
270 | break; | ||
271 | case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 | | ||
272 | EXT_CSD_CARD_TYPE_26: | ||
273 | card->ext_csd.hs_max_dtr = 52000000; | ||
274 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V; | ||
275 | break; | ||
261 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | 276 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: |
262 | card->ext_csd.hs_max_dtr = 52000000; | 277 | card->ext_csd.hs_max_dtr = 52000000; |
263 | break; | 278 | break; |
@@ -360,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
360 | struct mmc_card *oldcard) | 375 | struct mmc_card *oldcard) |
361 | { | 376 | { |
362 | struct mmc_card *card; | 377 | struct mmc_card *card; |
363 | int err; | 378 | int err, ddr = MMC_SDR_MODE; |
364 | u32 cid[4]; | 379 | u32 cid[4]; |
365 | unsigned int max_dtr; | 380 | unsigned int max_dtr; |
366 | 381 | ||
@@ -503,17 +518,35 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
503 | mmc_set_clock(host, max_dtr); | 518 | mmc_set_clock(host, max_dtr); |
504 | 519 | ||
505 | /* | 520 | /* |
506 | * Activate wide bus (if supported). | 521 | * Indicate DDR mode (if supported). |
522 | */ | ||
523 | if (mmc_card_highspeed(card)) { | ||
524 | if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) | ||
525 | && (host->caps & (MMC_CAP_1_8V_DDR))) | ||
526 | ddr = MMC_1_8V_DDR_MODE; | ||
527 | else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) | ||
528 | && (host->caps & (MMC_CAP_1_2V_DDR))) | ||
529 | ddr = MMC_1_2V_DDR_MODE; | ||
530 | } | ||
531 | |||
532 | /* | ||
533 | * Activate wide bus and DDR (if supported). | ||
507 | */ | 534 | */ |
508 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && | 535 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && |
509 | (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { | 536 | (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { |
510 | unsigned ext_csd_bit, bus_width; | 537 | unsigned ext_csd_bit, bus_width; |
511 | 538 | ||
512 | if (host->caps & MMC_CAP_8_BIT_DATA) { | 539 | if (host->caps & MMC_CAP_8_BIT_DATA) { |
513 | ext_csd_bit = EXT_CSD_BUS_WIDTH_8; | 540 | if (ddr) |
541 | ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8; | ||
542 | else | ||
543 | ext_csd_bit = EXT_CSD_BUS_WIDTH_8; | ||
514 | bus_width = MMC_BUS_WIDTH_8; | 544 | bus_width = MMC_BUS_WIDTH_8; |
515 | } else { | 545 | } else { |
516 | ext_csd_bit = EXT_CSD_BUS_WIDTH_4; | 546 | if (ddr) |
547 | ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4; | ||
548 | else | ||
549 | ext_csd_bit = EXT_CSD_BUS_WIDTH_4; | ||
517 | bus_width = MMC_BUS_WIDTH_4; | 550 | bus_width = MMC_BUS_WIDTH_4; |
518 | } | 551 | } |
519 | 552 | ||
@@ -524,12 +557,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
524 | goto free_card; | 557 | goto free_card; |
525 | 558 | ||
526 | if (err) { | 559 | if (err) { |
527 | printk(KERN_WARNING "%s: switch to bus width %d " | 560 | printk(KERN_WARNING "%s: switch to bus width %d ddr %d " |
528 | "failed\n", mmc_hostname(card->host), | 561 | "failed\n", mmc_hostname(card->host), |
529 | 1 << bus_width); | 562 | 1 << bus_width, ddr); |
530 | err = 0; | 563 | err = 0; |
531 | } else { | 564 | } else { |
532 | mmc_set_bus_width(card->host, bus_width); | 565 | mmc_card_set_ddr_mode(card); |
566 | mmc_set_bus_width_ddr(card->host, bus_width, ddr); | ||
533 | } | 567 | } |
534 | } | 568 | } |
535 | 569 | ||
@@ -623,12 +657,16 @@ static int mmc_resume(struct mmc_host *host) | |||
623 | return err; | 657 | return err; |
624 | } | 658 | } |
625 | 659 | ||
626 | static void mmc_power_restore(struct mmc_host *host) | 660 | static int mmc_power_restore(struct mmc_host *host) |
627 | { | 661 | { |
662 | int ret; | ||
663 | |||
628 | host->card->state &= ~MMC_STATE_HIGHSPEED; | 664 | host->card->state &= ~MMC_STATE_HIGHSPEED; |
629 | mmc_claim_host(host); | 665 | mmc_claim_host(host); |
630 | mmc_init_card(host, host->ocr, host->card); | 666 | ret = mmc_init_card(host, host->ocr, host->card); |
631 | mmc_release_host(host); | 667 | mmc_release_host(host); |
668 | |||
669 | return ret; | ||
632 | } | 670 | } |
633 | 671 | ||
634 | static int mmc_sleep(struct mmc_host *host) | 672 | static int mmc_sleep(struct mmc_host *host) |
@@ -685,7 +723,7 @@ static void mmc_attach_bus_ops(struct mmc_host *host) | |||
685 | { | 723 | { |
686 | const struct mmc_bus_ops *bus_ops; | 724 | const struct mmc_bus_ops *bus_ops; |
687 | 725 | ||
688 | if (host->caps & MMC_CAP_NONREMOVABLE || !mmc_assume_removable) | 726 | if (!mmc_card_is_removable(host)) |
689 | bus_ops = &mmc_ops_unsafe; | 727 | bus_ops = &mmc_ops_unsafe; |
690 | else | 728 | else |
691 | bus_ops = &mmc_ops; | 729 | bus_ops = &mmc_ops; |