diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/core/core.c | 9 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 1 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 152 | ||||
-rw-r--r-- | drivers/mmc/core/sd.h | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 4 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 27 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 11 |
7 files changed, 176 insertions, 30 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 5005a6323165..61c6c0b8f0e0 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 | */ | ||
989 | void 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 7745dea430b8..93f33973de39 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, | |||
43 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); | 43 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); |
44 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); | 44 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); |
45 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | 45 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); |
46 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); | ||
46 | 47 | ||
47 | static inline void mmc_delay(unsigned int ms) | 48 | static inline void mmc_delay(unsigned int ms) |
48 | { | 49 | { |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 8285842f19e9..5b7c99855635 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 | ||
403 | static 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 | */ | ||
458 | static 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 | |||
489 | out: | ||
490 | kfree(status); | ||
491 | |||
492 | return err; | ||
493 | } | ||
494 | |||
403 | MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], | 495 | MMC_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]); |
405 | MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | 497 | MMC_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 | */ |
451 | int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) | 543 | int 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 | ||
487 | try_again: | 578 | try_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 3d8800fa7600..4b34b24f3f76 100644 --- a/drivers/mmc/core/sd.h +++ b/drivers/mmc/core/sd.h | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | extern struct device_type sd_type; | 6 | extern struct device_type sd_type; |
7 | 7 | ||
8 | int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid); | 8 | int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr); |
9 | int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card); | 9 | int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card); |
10 | void mmc_decode_cid(struct mmc_card *card); | 10 | void mmc_decode_cid(struct mmc_card *card); |
11 | int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, | 11 | int 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 1e6095961500..4d0c15bfa514 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 || |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 4e2031449a23..8072e16d6d46 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1245,6 +1245,25 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1245 | 1245 | ||
1246 | sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); | 1246 | sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); |
1247 | 1247 | ||
1248 | if (host->version >= SDHCI_SPEC_300) { | ||
1249 | u16 ctrl_2; | ||
1250 | |||
1251 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | ||
1252 | if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) { | ||
1253 | /* | ||
1254 | * We only need to set Driver Strength if the | ||
1255 | * preset value enable is not set. | ||
1256 | */ | ||
1257 | ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK; | ||
1258 | if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) | ||
1259 | ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A; | ||
1260 | else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C) | ||
1261 | ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; | ||
1262 | |||
1263 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); | ||
1264 | } | ||
1265 | } | ||
1266 | |||
1248 | /* | 1267 | /* |
1249 | * Some (ENE) controllers go apeshit on some ios operation, | 1268 | * Some (ENE) controllers go apeshit on some ios operation, |
1250 | * signalling timeout and CRC errors even on CMD0. Resetting | 1269 | * signalling timeout and CRC errors even on CMD0. Resetting |
@@ -2086,6 +2105,14 @@ int sdhci_add_host(struct sdhci_host *host) | |||
2086 | if (caps[1] & SDHCI_SUPPORT_DDR50) | 2105 | if (caps[1] & SDHCI_SUPPORT_DDR50) |
2087 | mmc->caps |= MMC_CAP_UHS_DDR50; | 2106 | mmc->caps |= MMC_CAP_UHS_DDR50; |
2088 | 2107 | ||
2108 | /* Driver Type(s) (A, C, D) supported by the host */ | ||
2109 | if (caps[1] & SDHCI_DRIVER_TYPE_A) | ||
2110 | mmc->caps |= MMC_CAP_DRIVER_TYPE_A; | ||
2111 | if (caps[1] & SDHCI_DRIVER_TYPE_C) | ||
2112 | mmc->caps |= MMC_CAP_DRIVER_TYPE_C; | ||
2113 | if (caps[1] & SDHCI_DRIVER_TYPE_D) | ||
2114 | mmc->caps |= MMC_CAP_DRIVER_TYPE_D; | ||
2115 | |||
2089 | ocr_avail = 0; | 2116 | ocr_avail = 0; |
2090 | /* | 2117 | /* |
2091 | * According to SD Host Controller spec v3.00, if the Host System | 2118 | * According to SD Host Controller spec v3.00, if the Host System |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 5cba2fea46e0..667bf8874be7 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -71,7 +71,7 @@ | |||
71 | #define SDHCI_DATA_LVL_MASK 0x00F00000 | 71 | #define SDHCI_DATA_LVL_MASK 0x00F00000 |
72 | #define SDHCI_DATA_LVL_SHIFT 20 | 72 | #define SDHCI_DATA_LVL_SHIFT 20 |
73 | 73 | ||
74 | #define SDHCI_HOST_CONTROL 0x28 | 74 | #define SDHCI_HOST_CONTROL 0x28 |
75 | #define SDHCI_CTRL_LED 0x01 | 75 | #define SDHCI_CTRL_LED 0x01 |
76 | #define SDHCI_CTRL_4BITBUS 0x02 | 76 | #define SDHCI_CTRL_4BITBUS 0x02 |
77 | #define SDHCI_CTRL_HISPD 0x04 | 77 | #define SDHCI_CTRL_HISPD 0x04 |
@@ -150,6 +150,12 @@ | |||
150 | 150 | ||
151 | #define SDHCI_HOST_CONTROL2 0x3E | 151 | #define SDHCI_HOST_CONTROL2 0x3E |
152 | #define SDHCI_CTRL_VDD_180 0x0008 | 152 | #define SDHCI_CTRL_VDD_180 0x0008 |
153 | #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 | ||
154 | #define SDHCI_CTRL_DRV_TYPE_B 0x0000 | ||
155 | #define SDHCI_CTRL_DRV_TYPE_A 0x0010 | ||
156 | #define SDHCI_CTRL_DRV_TYPE_C 0x0020 | ||
157 | #define SDHCI_CTRL_DRV_TYPE_D 0x0030 | ||
158 | #define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 | ||
153 | 159 | ||
154 | #define SDHCI_CAPABILITIES 0x40 | 160 | #define SDHCI_CAPABILITIES 0x40 |
155 | #define SDHCI_TIMEOUT_CLK_MASK 0x0000003F | 161 | #define SDHCI_TIMEOUT_CLK_MASK 0x0000003F |
@@ -173,6 +179,9 @@ | |||
173 | #define SDHCI_SUPPORT_SDR50 0x00000001 | 179 | #define SDHCI_SUPPORT_SDR50 0x00000001 |
174 | #define SDHCI_SUPPORT_SDR104 0x00000002 | 180 | #define SDHCI_SUPPORT_SDR104 0x00000002 |
175 | #define SDHCI_SUPPORT_DDR50 0x00000004 | 181 | #define SDHCI_SUPPORT_DDR50 0x00000004 |
182 | #define SDHCI_DRIVER_TYPE_A 0x00000010 | ||
183 | #define SDHCI_DRIVER_TYPE_C 0x00000020 | ||
184 | #define SDHCI_DRIVER_TYPE_D 0x00000040 | ||
176 | 185 | ||
177 | #define SDHCI_CAPABILITIES_1 0x44 | 186 | #define SDHCI_CAPABILITIES_1 0x44 |
178 | 187 | ||