aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorArindam Nath <arindam.nath@amd.com>2011-05-05 02:48:59 -0400
committerChris Ball <cjb@laptop.org>2011-05-24 23:53:24 -0400
commitd6d50a15a2897d4133d536dd4343b5cf21163db3 (patch)
treeb56723c1b3e74ae2ae9e9d7fb39e916cdfa74958 /drivers/mmc/core
parent013909c4ffd16ded4895528b856fd8782df04dc6 (diff)
mmc: sd: add support for driver type selection
This patch adds support for setting driver strength during UHS-I initialization procedure. Since UHS-I cards set S18A (bit 24) in response to ACMD41, we use this as a base for UHS-I initialization. We modify the parameter list of mmc_sd_get_cid() so that we can save the ROCR from ACMD41 to check whether bit 24 is set. We decide whether the Host Controller supports A, C, or D driver type depending on the Capabilities register. Driver type B is suported by default. We then set the appropriate driver type for the card using CMD6 mode 1. As per Host Controller spec v3.00, we set driver type for the host only if Preset Value Enable in the Host Control2 register is not set. SDHCI_HOST_CONTROL has been renamed to SDHCI_HOST_CONTROL1 to conform to the spec. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath <arindam.nath@amd.com> Reviewed-by: Philip Rakity <prakity@marvell.com> Tested-by: Philip Rakity <prakity@marvell.com> Acked-by: Zhangfei Gao <zhangfei.gao@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/core.c9
-rw-r--r--drivers/mmc/core/core.h1
-rw-r--r--drivers/mmc/core/sd.c152
-rw-r--r--drivers/mmc/core/sd.h2
-rw-r--r--drivers/mmc/core/sdio.c4
5 files changed, 139 insertions, 29 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 5005a632316..61c6c0b8f0e 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -984,6 +984,15 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
984} 984}
985 985
986/* 986/*
987 * Select appropriate driver type for host.
988 */
989void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
990{
991 host->ios.drv_type = drv_type;
992 mmc_set_ios(host);
993}
994
995/*
987 * Apply power to the MMC stack. This is a two-stage process. 996 * Apply power to the MMC stack. This is a two-stage process.
988 * First, we enable power to the card without the clock running. 997 * First, we enable power to the card without the clock running.
989 * We then wait a bit for the power to stabilise. Finally, 998 * We then wait a bit for the power to stabilise. Finally,
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 7745dea430b..93f33973de3 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -43,6 +43,7 @@ void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
43u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); 43u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
44int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); 44int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
45void mmc_set_timing(struct mmc_host *host, unsigned int timing); 45void mmc_set_timing(struct mmc_host *host, unsigned int timing);
46void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
46 47
47static inline void mmc_delay(unsigned int ms) 48static inline void mmc_delay(unsigned int ms)
48{ 49{
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 8285842f19e..5b7c9985563 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -400,6 +400,98 @@ out:
400 return err; 400 return err;
401} 401}
402 402
403static int sd_select_driver_type(struct mmc_card *card, u8 *status)
404{
405 int host_drv_type = 0, card_drv_type = 0;
406 int err;
407
408 /*
409 * If the host doesn't support any of the Driver Types A,C or D,
410 * default Driver Type B is used.
411 */
412 if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C
413 | MMC_CAP_DRIVER_TYPE_D)))
414 return 0;
415
416 if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) {
417 host_drv_type = MMC_SET_DRIVER_TYPE_A;
418 if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A)
419 card_drv_type = MMC_SET_DRIVER_TYPE_A;
420 else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B)
421 card_drv_type = MMC_SET_DRIVER_TYPE_B;
422 else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
423 card_drv_type = MMC_SET_DRIVER_TYPE_C;
424 } else if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) {
425 host_drv_type = MMC_SET_DRIVER_TYPE_C;
426 if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
427 card_drv_type = MMC_SET_DRIVER_TYPE_C;
428 } else if (!(card->host->caps & MMC_CAP_DRIVER_TYPE_D)) {
429 /*
430 * If we are here, that means only the default driver type
431 * B is supported by the host.
432 */
433 host_drv_type = MMC_SET_DRIVER_TYPE_B;
434 if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B)
435 card_drv_type = MMC_SET_DRIVER_TYPE_B;
436 else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
437 card_drv_type = MMC_SET_DRIVER_TYPE_C;
438 }
439
440 err = mmc_sd_switch(card, 1, 2, card_drv_type, status);
441 if (err)
442 return err;
443
444 if ((status[15] & 0xF) != card_drv_type) {
445 printk(KERN_WARNING "%s: Problem setting driver strength!\n",
446 mmc_hostname(card->host));
447 return 0;
448 }
449
450 mmc_set_driver_type(card->host, host_drv_type);
451
452 return 0;
453}
454
455/*
456 * UHS-I specific initialization procedure
457 */
458static int mmc_sd_init_uhs_card(struct mmc_card *card)
459{
460 int err;
461 u8 *status;
462
463 if (!card->scr.sda_spec3)
464 return 0;
465
466 if (!(card->csd.cmdclass & CCC_SWITCH))
467 return 0;
468
469 status = kmalloc(64, GFP_KERNEL);
470 if (!status) {
471 printk(KERN_ERR "%s: could not allocate a buffer for "
472 "switch capabilities.\n", mmc_hostname(card->host));
473 return -ENOMEM;
474 }
475
476 /* Set 4-bit bus width */
477 if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&
478 (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
479 err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
480 if (err)
481 goto out;
482
483 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
484 }
485
486 /* Set the driver strength for the card */
487 err = sd_select_driver_type(card, status);
488
489out:
490 kfree(status);
491
492 return err;
493}
494
403MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], 495MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
404 card->raw_cid[2], card->raw_cid[3]); 496 card->raw_cid[2], card->raw_cid[3]);
405MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], 497MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
@@ -448,10 +540,9 @@ struct device_type sd_type = {
448/* 540/*
449 * Fetch CID from card. 541 * Fetch CID from card.
450 */ 542 */
451int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) 543int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
452{ 544{
453 int err; 545 int err;
454 u32 rocr;
455 546
456 /* 547 /*
457 * Since we're changing the OCR value, we seem to 548 * Since we're changing the OCR value, we seem to
@@ -485,7 +576,7 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
485 ocr |= SD_OCR_XPC; 576 ocr |= SD_OCR_XPC;
486 577
487try_again: 578try_again:
488 err = mmc_send_app_op_cond(host, ocr, &rocr); 579 err = mmc_send_app_op_cond(host, ocr, rocr);
489 if (err) 580 if (err)
490 return err; 581 return err;
491 582
@@ -493,7 +584,8 @@ try_again:
493 * In case CCS and S18A in the response is set, start Signal Voltage 584 * In case CCS and S18A in the response is set, start Signal Voltage
494 * Switch procedure. SPI mode doesn't support CMD11. 585 * Switch procedure. SPI mode doesn't support CMD11.
495 */ 586 */
496 if (!mmc_host_is_spi(host) && ((rocr & 0x41000000) == 0x41000000)) { 587 if (!mmc_host_is_spi(host) && rocr &&
588 ((*rocr & 0x41000000) == 0x41000000)) {
497 err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); 589 err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
498 if (err) { 590 if (err) {
499 ocr &= ~SD_OCR_S18R; 591 ocr &= ~SD_OCR_S18R;
@@ -628,11 +720,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
628 struct mmc_card *card; 720 struct mmc_card *card;
629 int err; 721 int err;
630 u32 cid[4]; 722 u32 cid[4];
723 u32 rocr = 0;
631 724
632 BUG_ON(!host); 725 BUG_ON(!host);
633 WARN_ON(!host->claimed); 726 WARN_ON(!host->claimed);
634 727
635 err = mmc_sd_get_cid(host, ocr, cid); 728 err = mmc_sd_get_cid(host, ocr, cid, &rocr);
636 if (err) 729 if (err)
637 return err; 730 return err;
638 731
@@ -685,30 +778,37 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
685 if (err) 778 if (err)
686 goto free_card; 779 goto free_card;
687 780
688 /* 781 /* Initialization sequence for UHS-I cards */
689 * Attempt to change to high-speed (if supported) 782 if (rocr & SD_ROCR_S18A) {
690 */ 783 err = mmc_sd_init_uhs_card(card);
691 err = mmc_sd_switch_hs(card);
692 if (err > 0)
693 mmc_sd_go_highspeed(card);
694 else if (err)
695 goto free_card;
696
697 /*
698 * Set bus speed.
699 */
700 mmc_set_clock(host, mmc_sd_get_max_clock(card));
701
702 /*
703 * Switch to wider bus (if supported).
704 */
705 if ((host->caps & MMC_CAP_4_BIT_DATA) &&
706 (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
707 err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
708 if (err) 784 if (err)
709 goto free_card; 785 goto free_card;
786 } else {
787 /*
788 * Attempt to change to high-speed (if supported)
789 */
790 err = mmc_sd_switch_hs(card);
791 if (err > 0)
792 mmc_sd_go_highspeed(card);
793 else if (err)
794 goto free_card;
795
796 /*
797 * Set bus speed.
798 */
799 mmc_set_clock(host, mmc_sd_get_max_clock(card));
710 800
711 mmc_set_bus_width(host, MMC_BUS_WIDTH_4); 801 /*
802 * Switch to wider bus (if supported).
803 */
804 if ((host->caps & MMC_CAP_4_BIT_DATA) &&
805 (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
806 err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
807 if (err)
808 goto free_card;
809
810 mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
811 }
712 } 812 }
713 813
714 host->card = card; 814 host->card = card;
diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h
index 3d8800fa760..4b34b24f3f7 100644
--- a/drivers/mmc/core/sd.h
+++ b/drivers/mmc/core/sd.h
@@ -5,7 +5,7 @@
5 5
6extern struct device_type sd_type; 6extern struct device_type sd_type;
7 7
8int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid); 8int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr);
9int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card); 9int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card);
10void mmc_decode_cid(struct mmc_card *card); 10void mmc_decode_cid(struct mmc_card *card);
11int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, 11int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 1e609596150..4d0c15bfa51 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -369,8 +369,8 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
369 goto err; 369 goto err;
370 } 370 }
371 371
372 if (ocr & R4_MEMORY_PRESENT 372 if ((ocr & R4_MEMORY_PRESENT) &&
373 && mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid) == 0) { 373 mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid, NULL) == 0) {
374 card->type = MMC_TYPE_SD_COMBO; 374 card->type = MMC_TYPE_SD_COMBO;
375 375
376 if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || 376 if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||