aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorPhilip Rakity <prakity@marvell.com>2011-11-14 22:14:38 -0500
committerChris Ball <cjb@laptop.org>2012-01-11 23:58:41 -0500
commita303c5319c8e6ab0e744ebca118da8420043b2c3 (patch)
treec4b307137f68551b4d30fefab6f9ec2760d3f7eb /drivers/mmc/core
parentb70a7fab26db65f7daaf04f49a3bd673250f48c7 (diff)
mmc: sdio: support SDIO UHS cards
This patch adds support for sdio UHS cards per the version 3.0 spec. UHS mode is only enabled for version 3.0 cards when both the host and the controller support UHS modes. 1.8v signaling support is removed if both the card and the host do not support UHS. This is done to maintain compatibility and some system/card combinations break when 1.8v signaling is enabled when the host does not support UHS. Signed-off-by: Philip Rakity <prakity@marvell.com> Signed-off-by: Aaron Lu <Aaron.lu@amd.com> Reviewed-by: Arindam Nath <arindam.nath@amd.com> Tested-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/bus.c2
-rw-r--r--drivers/mmc/core/sd.c2
-rw-r--r--drivers/mmc/core/sdio.c329
3 files changed, 306 insertions, 27 deletions
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 6be49249895a..f8a228a61fd4 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -305,7 +305,7 @@ int mmc_add_card(struct mmc_card *card)
305 } else { 305 } else {
306 printk(KERN_INFO "%s: new %s%s%s card at address %04x\n", 306 printk(KERN_INFO "%s: new %s%s%s card at address %04x\n",
307 mmc_hostname(card->host), 307 mmc_hostname(card->host),
308 mmc_sd_card_uhs(card) ? "ultra high speed " : 308 mmc_card_uhs(card) ? "ultra high speed " :
309 (mmc_card_highspeed(card) ? "high speed " : ""), 309 (mmc_card_highspeed(card) ? "high speed " : ""),
310 mmc_card_ddr_mode(card) ? "DDR " : "", 310 mmc_card_ddr_mode(card) ? "DDR " : "",
311 type, card->rca); 311 type, card->rca);
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index f54392c4638a..85b858f6d5d4 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -960,7 +960,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
960 goto free_card; 960 goto free_card;
961 961
962 /* Card is an ultra-high-speed card */ 962 /* Card is an ultra-high-speed card */
963 mmc_sd_card_set_uhs(card); 963 mmc_card_set_uhs(card);
964 964
965 /* 965 /*
966 * Since initialization is now complete, enable preset 966 * Since initialization is now complete, enable preset
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 3ab565e32a6a..8c04f7f46dec 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -102,6 +102,7 @@ static int sdio_read_cccr(struct mmc_card *card)
102 int ret; 102 int ret;
103 int cccr_vsn; 103 int cccr_vsn;
104 unsigned char data; 104 unsigned char data;
105 unsigned char speed;
105 106
106 memset(&card->cccr, 0, sizeof(struct sdio_cccr)); 107 memset(&card->cccr, 0, sizeof(struct sdio_cccr));
107 108
@@ -140,12 +141,60 @@ static int sdio_read_cccr(struct mmc_card *card)
140 } 141 }
141 142
142 if (cccr_vsn >= SDIO_CCCR_REV_1_20) { 143 if (cccr_vsn >= SDIO_CCCR_REV_1_20) {
143 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); 144 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
144 if (ret) 145 if (ret)
145 goto out; 146 goto out;
146 147
147 if (data & SDIO_SPEED_SHS) 148 card->scr.sda_spec3 = 0;
148 card->cccr.high_speed = 1; 149 card->sw_caps.sd3_bus_mode = 0;
150 card->sw_caps.sd3_drv_type = 0;
151 if (cccr_vsn >= SDIO_CCCR_REV_3_00) {
152 card->scr.sda_spec3 = 1;
153 ret = mmc_io_rw_direct(card, 0, 0,
154 SDIO_CCCR_UHS, 0, &data);
155 if (ret)
156 goto out;
157
158 if (card->host->caps &
159 (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
160 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
161 MMC_CAP_UHS_DDR50)) {
162 if (data & SDIO_UHS_DDR50)
163 card->sw_caps.sd3_bus_mode
164 |= SD_MODE_UHS_DDR50;
165
166 if (data & SDIO_UHS_SDR50)
167 card->sw_caps.sd3_bus_mode
168 |= SD_MODE_UHS_SDR50;
169
170 if (data & SDIO_UHS_SDR104)
171 card->sw_caps.sd3_bus_mode
172 |= SD_MODE_UHS_SDR104;
173 }
174
175 ret = mmc_io_rw_direct(card, 0, 0,
176 SDIO_CCCR_DRIVE_STRENGTH, 0, &data);
177 if (ret)
178 goto out;
179
180 if (data & SDIO_DRIVE_SDTA)
181 card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_A;
182 if (data & SDIO_DRIVE_SDTC)
183 card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
184 if (data & SDIO_DRIVE_SDTD)
185 card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
186 }
187
188 /* if no uhs mode ensure we check for high speed */
189 if (!card->sw_caps.sd3_bus_mode) {
190 if (speed & SDIO_SPEED_SHS) {
191 card->cccr.high_speed = 1;
192 card->sw_caps.hs_max_dtr = 50000000;
193 } else {
194 card->cccr.high_speed = 0;
195 card->sw_caps.hs_max_dtr = 25000000;
196 }
197 }
149 } 198 }
150 199
151out: 200out:
@@ -327,6 +376,193 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card)
327 return max_dtr; 376 return max_dtr;
328} 377}
329 378
379static unsigned char host_drive_to_sdio_drive(int host_strength)
380{
381 switch (host_strength) {
382 case MMC_SET_DRIVER_TYPE_A:
383 return SDIO_DTSx_SET_TYPE_A;
384 case MMC_SET_DRIVER_TYPE_B:
385 return SDIO_DTSx_SET_TYPE_B;
386 case MMC_SET_DRIVER_TYPE_C:
387 return SDIO_DTSx_SET_TYPE_C;
388 case MMC_SET_DRIVER_TYPE_D:
389 return SDIO_DTSx_SET_TYPE_D;
390 default:
391 return SDIO_DTSx_SET_TYPE_B;
392 }
393}
394
395static void sdio_select_driver_type(struct mmc_card *card)
396{
397 int host_drv_type = SD_DRIVER_TYPE_B;
398 int card_drv_type = SD_DRIVER_TYPE_B;
399 int drive_strength;
400 unsigned char card_strength;
401 int err;
402
403 /*
404 * If the host doesn't support any of the Driver Types A,C or D,
405 * or there is no board specific handler then default Driver
406 * Type B is used.
407 */
408 if (!(card->host->caps &
409 (MMC_CAP_DRIVER_TYPE_A |
410 MMC_CAP_DRIVER_TYPE_C |
411 MMC_CAP_DRIVER_TYPE_D)))
412 return;
413
414 if (!card->host->ops->select_drive_strength)
415 return;
416
417 if (card->host->caps & MMC_CAP_DRIVER_TYPE_A)
418 host_drv_type |= SD_DRIVER_TYPE_A;
419
420 if (card->host->caps & MMC_CAP_DRIVER_TYPE_C)
421 host_drv_type |= SD_DRIVER_TYPE_C;
422
423 if (card->host->caps & MMC_CAP_DRIVER_TYPE_D)
424 host_drv_type |= SD_DRIVER_TYPE_D;
425
426 if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A)
427 card_drv_type |= SD_DRIVER_TYPE_A;
428
429 if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
430 card_drv_type |= SD_DRIVER_TYPE_C;
431
432 if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_D)
433 card_drv_type |= SD_DRIVER_TYPE_D;
434
435 /*
436 * The drive strength that the hardware can support
437 * depends on the board design. Pass the appropriate
438 * information and let the hardware specific code
439 * return what is possible given the options
440 */
441 drive_strength = card->host->ops->select_drive_strength(
442 card->sw_caps.uhs_max_dtr,
443 host_drv_type, card_drv_type);
444
445 /* if error just use default for drive strength B */
446 err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0,
447 &card_strength);
448 if (err)
449 return;
450
451 card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT);
452 card_strength |= host_drive_to_sdio_drive(drive_strength);
453
454 err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH,
455 card_strength, NULL);
456
457 /* if error default to drive strength B */
458 if (!err)
459 mmc_set_driver_type(card->host, drive_strength);
460}
461
462
463static int sdio_set_bus_speed_mode(struct mmc_card *card)
464{
465 unsigned int bus_speed, timing;
466 int err;
467 unsigned char speed;
468
469 /*
470 * If the host doesn't support any of the UHS-I modes, fallback on
471 * default speed.
472 */
473 if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
474 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
475 return 0;
476
477 bus_speed = SDIO_SPEED_SDR12;
478 timing = MMC_TIMING_UHS_SDR12;
479 if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
480 (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
481 bus_speed = SDIO_SPEED_SDR104;
482 timing = MMC_TIMING_UHS_SDR104;
483 card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
484 } else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
485 (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
486 bus_speed = SDIO_SPEED_DDR50;
487 timing = MMC_TIMING_UHS_DDR50;
488 card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
489 } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
490 MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
491 SD_MODE_UHS_SDR50)) {
492 bus_speed = SDIO_SPEED_SDR50;
493 timing = MMC_TIMING_UHS_SDR50;
494 card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
495 } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
496 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
497 (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
498 bus_speed = SDIO_SPEED_SDR25;
499 timing = MMC_TIMING_UHS_SDR25;
500 card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
501 } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
502 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
503 MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
504 SD_MODE_UHS_SDR12)) {
505 bus_speed = SDIO_SPEED_SDR12;
506 timing = MMC_TIMING_UHS_SDR12;
507 card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
508 }
509
510 err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
511 if (err)
512 return err;
513
514 speed &= ~SDIO_SPEED_BSS_MASK;
515 speed |= bus_speed;
516 err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
517 if (err)
518 return err;
519
520 if (bus_speed) {
521 mmc_set_timing(card->host, timing);
522 mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
523 }
524
525 return 0;
526}
527
528/*
529 * UHS-I specific initialization procedure
530 */
531static int mmc_sdio_init_uhs_card(struct mmc_card *card)
532{
533 int err;
534
535 if (!card->scr.sda_spec3)
536 return 0;
537
538 /*
539 * Switch to wider bus (if supported).
540 */
541 if (card->host->caps & MMC_CAP_4_BIT_DATA) {
542 err = sdio_enable_4bit_bus(card);
543 if (err > 0) {
544 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
545 err = 0;
546 }
547 }
548
549 /* Set the driver strength for the card */
550 sdio_select_driver_type(card);
551
552 /* Set bus speed mode of the card */
553 err = sdio_set_bus_speed_mode(card);
554 if (err)
555 goto out;
556
557 /* Initialize and start re-tuning timer */
558 if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
559 err = card->host->ops->execute_tuning(card->host);
560
561out:
562
563 return err;
564}
565
330/* 566/*
331 * Handle the detection and initialisation of a card. 567 * Handle the detection and initialisation of a card.
332 * 568 *
@@ -394,6 +630,30 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
394 host->ops->init_card(host, card); 630 host->ops->init_card(host, card);
395 631
396 /* 632 /*
633 * If the host and card support UHS-I mode request the card
634 * to switch to 1.8V signaling level. No 1.8v signalling if
635 * UHS mode is not enabled to maintain compatibilty and some
636 * systems that claim 1.8v signalling in fact do not support
637 * it.
638 */
639 if ((ocr & R4_18V_PRESENT) &&
640 (host->caps &
641 (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
642 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
643 MMC_CAP_UHS_DDR50))) {
644 err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
645 true);
646 if (err) {
647 ocr &= ~R4_18V_PRESENT;
648 host->ocr &= ~R4_18V_PRESENT;
649 }
650 err = 0;
651 } else {
652 ocr &= ~R4_18V_PRESENT;
653 host->ocr &= ~R4_18V_PRESENT;
654 }
655
656 /*
397 * For native busses: set card RCA and quit open drain mode. 657 * For native busses: set card RCA and quit open drain mode.
398 */ 658 */
399 if (!powered_resume && !mmc_host_is_spi(host)) { 659 if (!powered_resume && !mmc_host_is_spi(host)) {
@@ -492,29 +752,39 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
492 if (err) 752 if (err)
493 goto remove; 753 goto remove;
494 754
495 /* 755 /* Initialization sequence for UHS-I cards */
496 * Switch to high-speed (if supported). 756 /* Only if card supports 1.8v and UHS signaling */
497 */ 757 if ((ocr & R4_18V_PRESENT) && card->sw_caps.sd3_bus_mode) {
498 err = sdio_enable_hs(card); 758 err = mmc_sdio_init_uhs_card(card);
499 if (err > 0) 759 if (err)
500 mmc_sd_go_highspeed(card); 760 goto remove;
501 else if (err)
502 goto remove;
503 761
504 /* 762 /* Card is an ultra-high-speed card */
505 * Change to the card's maximum speed. 763 mmc_card_set_uhs(card);
506 */ 764 } else {
507 mmc_set_clock(host, mmc_sdio_get_max_clock(card)); 765 /*
766 * Switch to high-speed (if supported).
767 */
768 err = sdio_enable_hs(card);
769 if (err > 0)
770 mmc_sd_go_highspeed(card);
771 else if (err)
772 goto remove;
508 773
509 /* 774 /*
510 * Switch to wider bus (if supported). 775 * Change to the card's maximum speed.
511 */ 776 */
512 err = sdio_enable_4bit_bus(card); 777 mmc_set_clock(host, mmc_sdio_get_max_clock(card));
513 if (err > 0)
514 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
515 else if (err)
516 goto remove;
517 778
779 /*
780 * Switch to wider bus (if supported).
781 */
782 err = sdio_enable_4bit_bus(card);
783 if (err > 0)
784 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
785 else if (err)
786 goto remove;
787 }
518finish: 788finish:
519 if (!oldcard) 789 if (!oldcard)
520 host->card = card; 790 host->card = card;
@@ -797,8 +1067,17 @@ int mmc_attach_sdio(struct mmc_host *host)
797 * Detect and init the card. 1067 * Detect and init the card.
798 */ 1068 */
799 err = mmc_sdio_init_card(host, host->ocr, NULL, 0); 1069 err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
800 if (err) 1070 if (err) {
801 goto err; 1071 if (err == -EAGAIN) {
1072 /*
1073 * Retry initialization with S18R set to 0.
1074 */
1075 host->ocr &= ~R4_18V_PRESENT;
1076 err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
1077 }
1078 if (err)
1079 goto err;
1080 }
802 card = host->card; 1081 card = host->card;
803 1082
804 /* 1083 /*