aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorGirish K S <girish.shivananjappa@linaro.org>2012-01-11 14:04:52 -0500
committerChris Ball <cjb@laptop.org>2012-01-12 15:17:15 -0500
commita4924c71aa43d4f8a3f342b1f71788349472e684 (patch)
tree19de11b280fca6718e5e766feaa53a43a9a6cb58 /drivers/mmc
parentee5d19b20a711dca3848450979e3cd20b6b795cc (diff)
mmc: core: HS200 mode support for eMMC 4.5
This patch adds the support of the HS200 bus speed for eMMC 4.5 devices. The eMMC 4.5 devices have support for 200MHz bus speed. The function prototype of the tuning function is modified to handle the tuning command number which is different in sd and mmc case. Signed-off-by: Girish K S <girish.shivananjappa@linaro.org> Signed-off-by: Philip Rakity <prakity@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/bus.c3
-rw-r--r--drivers/mmc/core/debugfs.c3
-rw-r--r--drivers/mmc/core/mmc.c162
-rw-r--r--drivers/mmc/core/sd.c3
-rw-r--r--drivers/mmc/core/sdio.c4
5 files changed, 163 insertions, 12 deletions
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index f8a228a61fd4..5d011a39dfff 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -303,10 +303,11 @@ int mmc_add_card(struct mmc_card *card)
303 mmc_card_ddr_mode(card) ? "DDR " : "", 303 mmc_card_ddr_mode(card) ? "DDR " : "",
304 type); 304 type);
305 } else { 305 } else {
306 printk(KERN_INFO "%s: new %s%s%s card at address %04x\n", 306 pr_info("%s: new %s%s%s%s card at address %04x\n",
307 mmc_hostname(card->host), 307 mmc_hostname(card->host),
308 mmc_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_hs200(card) ? "HS200 " : ""),
310 mmc_card_ddr_mode(card) ? "DDR " : "", 311 mmc_card_ddr_mode(card) ? "DDR " : "",
311 type, card->rca); 312 type, card->rca);
312 } 313 }
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 027615d3bf3e..9ab5b17d488a 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -135,6 +135,9 @@ static int mmc_ios_show(struct seq_file *s, void *data)
135 case MMC_TIMING_UHS_DDR50: 135 case MMC_TIMING_UHS_DDR50:
136 str = "sd uhs DDR50"; 136 str = "sd uhs DDR50";
137 break; 137 break;
138 case MMC_TIMING_MMC_HS200:
139 str = "mmc high-speed SDR200";
140 break;
138 default: 141 default:
139 str = "invalid"; 142 str = "invalid";
140 break; 143 break;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 67f346e0d105..59b9ba52e66a 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -286,6 +286,27 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
286 } 286 }
287 card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; 287 card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
288 switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { 288 switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
289 case EXT_CSD_CARD_TYPE_SDR_ALL:
290 case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V:
291 case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V:
292 case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52:
293 card->ext_csd.hs_max_dtr = 200000000;
294 card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200;
295 break;
296 case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL:
297 case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V:
298 case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V:
299 case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52:
300 card->ext_csd.hs_max_dtr = 200000000;
301 card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V;
302 break;
303 case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL:
304 case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V:
305 case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V:
306 case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52:
307 card->ext_csd.hs_max_dtr = 200000000;
308 card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V;
309 break;
289 case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | 310 case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
290 EXT_CSD_CARD_TYPE_26: 311 EXT_CSD_CARD_TYPE_26:
291 card->ext_csd.hs_max_dtr = 52000000; 312 card->ext_csd.hs_max_dtr = 52000000;
@@ -700,6 +721,79 @@ static int mmc_select_powerclass(struct mmc_card *card,
700} 721}
701 722
702/* 723/*
724 * Selects the desired buswidth and switch to the HS200 mode
725 * if bus width set without error
726 */
727static int mmc_select_hs200(struct mmc_card *card)
728{
729 int idx, err = 0;
730 struct mmc_host *host;
731 static unsigned ext_csd_bits[] = {
732 EXT_CSD_BUS_WIDTH_4,
733 EXT_CSD_BUS_WIDTH_8,
734 };
735 static unsigned bus_widths[] = {
736 MMC_BUS_WIDTH_4,
737 MMC_BUS_WIDTH_8,
738 };
739
740 BUG_ON(!card);
741
742 host = card->host;
743
744 if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V &&
745 host->caps2 & MMC_CAP2_HS200_1_2V_SDR)
746 if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0))
747 err = mmc_set_signal_voltage(host,
748 MMC_SIGNAL_VOLTAGE_180, 0);
749
750 /* If fails try again during next card power cycle */
751 if (err)
752 goto err;
753
754 idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 1 : 0;
755
756 /*
757 * Unlike SD, MMC cards dont have a configuration register to notify
758 * supported bus width. So bus test command should be run to identify
759 * the supported bus width or compare the ext csd values of current
760 * bus width and ext csd values of 1 bit mode read earlier.
761 */
762 for (; idx >= 0; idx--) {
763
764 /*
765 * Host is capable of 8bit transfer, then switch
766 * the device to work in 8bit transfer mode. If the
767 * mmc switch command returns error then switch to
768 * 4bit transfer mode. On success set the corresponding
769 * bus width on the host.
770 */
771 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
772 EXT_CSD_BUS_WIDTH,
773 ext_csd_bits[idx],
774 card->ext_csd.generic_cmd6_time);
775 if (err)
776 continue;
777
778 mmc_set_bus_width(card->host, bus_widths[idx]);
779
780 if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
781 err = mmc_compare_ext_csds(card, bus_widths[idx]);
782 else
783 err = mmc_bus_test(card, bus_widths[idx]);
784 if (!err)
785 break;
786 }
787
788 /* switch to HS200 mode if bus width set successfully */
789 if (!err)
790 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
791 EXT_CSD_HS_TIMING, 2, 0);
792err:
793 return err;
794}
795
796/*
703 * Handle the detection and initialisation of a card. 797 * Handle the detection and initialisation of a card.
704 * 798 *
705 * In the case of a resume, "oldcard" will contain the card 799 * In the case of a resume, "oldcard" will contain the card
@@ -905,11 +999,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
905 /* 999 /*
906 * Activate high speed (if supported) 1000 * Activate high speed (if supported)
907 */ 1001 */
908 if ((card->ext_csd.hs_max_dtr != 0) && 1002 if (card->ext_csd.hs_max_dtr != 0) {
909 (host->caps & MMC_CAP_MMC_HIGHSPEED)) { 1003 err = 0;
910 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1004 if (card->ext_csd.hs_max_dtr > 52000000 &&
911 EXT_CSD_HS_TIMING, 1, 1005 host->caps2 & MMC_CAP2_HS200)
912 card->ext_csd.generic_cmd6_time); 1006 err = mmc_select_hs200(card);
1007 else if (host->caps & MMC_CAP_MMC_HIGHSPEED)
1008 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1009 EXT_CSD_HS_TIMING, 1, 0);
1010
913 if (err && err != -EBADMSG) 1011 if (err && err != -EBADMSG)
914 goto free_card; 1012 goto free_card;
915 1013
@@ -918,8 +1016,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
918 mmc_hostname(card->host)); 1016 mmc_hostname(card->host));
919 err = 0; 1017 err = 0;
920 } else { 1018 } else {
921 mmc_card_set_highspeed(card); 1019 if (card->ext_csd.hs_max_dtr > 52000000 &&
922 mmc_set_timing(card->host, MMC_TIMING_MMC_HS); 1020 host->caps2 & MMC_CAP2_HS200) {
1021 mmc_card_set_hs200(card);
1022 mmc_set_timing(card->host,
1023 MMC_TIMING_MMC_HS200);
1024 } else {
1025 mmc_card_set_highspeed(card);
1026 mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
1027 }
923 } 1028 }
924 } 1029 }
925 1030
@@ -944,7 +1049,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
944 */ 1049 */
945 max_dtr = (unsigned int)-1; 1050 max_dtr = (unsigned int)-1;
946 1051
947 if (mmc_card_highspeed(card)) { 1052 if (mmc_card_highspeed(card) || mmc_card_hs200(card)) {
948 if (max_dtr > card->ext_csd.hs_max_dtr) 1053 if (max_dtr > card->ext_csd.hs_max_dtr)
949 max_dtr = card->ext_csd.hs_max_dtr; 1054 max_dtr = card->ext_csd.hs_max_dtr;
950 } else if (max_dtr > card->csd.max_dtr) { 1055 } else if (max_dtr > card->csd.max_dtr) {
@@ -970,9 +1075,48 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
970 } 1075 }
971 1076
972 /* 1077 /*
1078 * Indicate HS200 SDR mode (if supported).
1079 */
1080 if (mmc_card_hs200(card)) {
1081 u32 ext_csd_bits;
1082 u32 bus_width = card->host->ios.bus_width;
1083
1084 /*
1085 * For devices supporting HS200 mode, the bus width has
1086 * to be set before executing the tuning function. If
1087 * set before tuning, then device will respond with CRC
1088 * errors for responses on CMD line. So for HS200 the
1089 * sequence will be
1090 * 1. set bus width 4bit / 8 bit (1 bit not supported)
1091 * 2. switch to HS200 mode
1092 * 3. set the clock to > 52Mhz <=200MHz and
1093 * 4. execute tuning for HS200
1094 */
1095 if ((host->caps2 & MMC_CAP2_HS200) &&
1096 card->host->ops->execute_tuning)
1097 err = card->host->ops->execute_tuning(card->host,
1098 MMC_SEND_TUNING_BLOCK_HS200);
1099 if (err) {
1100 pr_warning("%s: tuning execution failed\n",
1101 mmc_hostname(card->host));
1102 goto err;
1103 }
1104
1105 ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
1106 EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
1107 err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
1108 if (err) {
1109 pr_err("%s: power class selection to bus width %d failed\n",
1110 mmc_hostname(card->host), 1 << bus_width);
1111 goto err;
1112 }
1113 }
1114
1115 /*
973 * Activate wide bus and DDR (if supported). 1116 * Activate wide bus and DDR (if supported).
974 */ 1117 */
975 if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && 1118 if (!mmc_card_hs200(card) &&
1119 (card->csd.mmca_vsn >= CSD_SPEC_VER_3) &&
976 (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { 1120 (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
977 static unsigned ext_csd_bits[][2] = { 1121 static unsigned ext_csd_bits[][2] = {
978 { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, 1122 { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 6f27d35081b8..c63ad03c29c7 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -661,7 +661,8 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
661 661
662 /* SPI mode doesn't define CMD19 */ 662 /* SPI mode doesn't define CMD19 */
663 if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) 663 if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
664 err = card->host->ops->execute_tuning(card->host); 664 err = card->host->ops->execute_tuning(card->host,
665 MMC_SEND_TUNING_BLOCK);
665 666
666out: 667out:
667 kfree(status); 668 kfree(status);
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index b77f770ce5d1..bd7bacc950dc 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/mmc/host.h> 15#include <linux/mmc/host.h>
16#include <linux/mmc/card.h> 16#include <linux/mmc/card.h>
17#include <linux/mmc/mmc.h>
17#include <linux/mmc/sdio.h> 18#include <linux/mmc/sdio.h>
18#include <linux/mmc/sdio_func.h> 19#include <linux/mmc/sdio_func.h>
19#include <linux/mmc/sdio_ids.h> 20#include <linux/mmc/sdio_ids.h>
@@ -556,7 +557,8 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card)
556 557
557 /* Initialize and start re-tuning timer */ 558 /* Initialize and start re-tuning timer */
558 if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) 559 if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
559 err = card->host->ops->execute_tuning(card->host); 560 err = card->host->ops->execute_tuning(card->host,
561 MMC_SEND_TUNING_BLOCK);
560 562
561out: 563out:
562 564