aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2014-04-23 04:14:58 -0400
committerChris Ball <chris@printf.net>2014-05-12 18:06:06 -0400
commit0a5b6438ee482696360bb013e67b8488f63d3e9e (patch)
tree1db1f058b17823a6ae4722c21d7f916e129694c4
parent577fb13199b11d8cd75609183649be4b5561243f (diff)
mmc: add support for HS400 mode of eMMC5.0
This patch adds HS400 mode support for eMMC5.0 device. HS400 mode is high speed DDR interface timing from HS200. Clock frequency is up to 200MHz and only 8-bit bus width is supported. In addition, tuning process of HS200 is required to synchronize the command response on the CMD line because CMD input timing for HS400 mode is the same as HS200 mode. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Reviewed-by: Jackey Shen <jackey.shen@amd.com> Tested-by: Jaehoon Chung <jh80.chung@samsung.com> Acked-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
-rw-r--r--drivers/mmc/core/bus.c1
-rw-r--r--drivers/mmc/core/debugfs.c3
-rw-r--r--drivers/mmc/core/mmc.c98
-rw-r--r--include/linux/mmc/card.h1
-rw-r--r--include/linux/mmc/host.h14
-rw-r--r--include/linux/mmc/mmc.h7
6 files changed, 118 insertions, 6 deletions
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index f37e9d6af84a..d2dbf02022bd 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -349,6 +349,7 @@ int mmc_add_card(struct mmc_card *card)
349 mmc_hostname(card->host), 349 mmc_hostname(card->host),
350 mmc_card_uhs(card) ? "ultra high speed " : 350 mmc_card_uhs(card) ? "ultra high speed " :
351 (mmc_card_hs(card) ? "high speed " : ""), 351 (mmc_card_hs(card) ? "high speed " : ""),
352 mmc_card_hs400(card) ? "HS400 " :
352 (mmc_card_hs200(card) ? "HS200 " : ""), 353 (mmc_card_hs200(card) ? "HS200 " : ""),
353 mmc_card_ddr52(card) ? "DDR " : "", 354 mmc_card_ddr52(card) ? "DDR " : "",
354 uhs_bus_speed_mode, type, card->rca); 355 uhs_bus_speed_mode, type, card->rca);
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 1f730dbfaeea..91eb16223246 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -141,6 +141,9 @@ static int mmc_ios_show(struct seq_file *s, void *data)
141 case MMC_TIMING_MMC_HS200: 141 case MMC_TIMING_MMC_HS200:
142 str = "mmc HS200"; 142 str = "mmc HS200";
143 break; 143 break;
144 case MMC_TIMING_MMC_HS400:
145 str = "mmc HS400";
146 break;
144 default: 147 default:
145 str = "invalid"; 148 str = "invalid";
146 break; 149 break;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index bec6786efd19..793c6f7ddb04 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -240,7 +240,7 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
240static void mmc_select_card_type(struct mmc_card *card) 240static void mmc_select_card_type(struct mmc_card *card)
241{ 241{
242 struct mmc_host *host = card->host; 242 struct mmc_host *host = card->host;
243 u8 card_type = card->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_MASK; 243 u8 card_type = card->ext_csd.raw_card_type;
244 u32 caps = host->caps, caps2 = host->caps2; 244 u32 caps = host->caps, caps2 = host->caps2;
245 unsigned int hs_max_dtr = 0, hs200_max_dtr = 0; 245 unsigned int hs_max_dtr = 0, hs200_max_dtr = 0;
246 unsigned int avail_type = 0; 246 unsigned int avail_type = 0;
@@ -281,6 +281,18 @@ static void mmc_select_card_type(struct mmc_card *card)
281 avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V; 281 avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V;
282 } 282 }
283 283
284 if (caps2 & MMC_CAP2_HS400_1_8V &&
285 card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) {
286 hs200_max_dtr = MMC_HS200_MAX_DTR;
287 avail_type |= EXT_CSD_CARD_TYPE_HS400_1_8V;
288 }
289
290 if (caps2 & MMC_CAP2_HS400_1_2V &&
291 card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) {
292 hs200_max_dtr = MMC_HS200_MAX_DTR;
293 avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V;
294 }
295
284 card->ext_csd.hs_max_dtr = hs_max_dtr; 296 card->ext_csd.hs_max_dtr = hs_max_dtr;
285 card->ext_csd.hs200_max_dtr = hs200_max_dtr; 297 card->ext_csd.hs200_max_dtr = hs200_max_dtr;
286 card->mmc_avail_type = avail_type; 298 card->mmc_avail_type = avail_type;
@@ -499,6 +511,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
499 ext_csd[EXT_CSD_PWR_CL_DDR_52_195]; 511 ext_csd[EXT_CSD_PWR_CL_DDR_52_195];
500 card->ext_csd.raw_pwr_cl_ddr_52_360 = 512 card->ext_csd.raw_pwr_cl_ddr_52_360 =
501 ext_csd[EXT_CSD_PWR_CL_DDR_52_360]; 513 ext_csd[EXT_CSD_PWR_CL_DDR_52_360];
514 card->ext_csd.raw_pwr_cl_ddr_200_360 =
515 ext_csd[EXT_CSD_PWR_CL_DDR_200_360];
502 } 516 }
503 517
504 if (card->ext_csd.rev >= 5) { 518 if (card->ext_csd.rev >= 5) {
@@ -665,7 +679,10 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width)
665 (card->ext_csd.raw_pwr_cl_ddr_52_195 == 679 (card->ext_csd.raw_pwr_cl_ddr_52_195 ==
666 bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) && 680 bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) &&
667 (card->ext_csd.raw_pwr_cl_ddr_52_360 == 681 (card->ext_csd.raw_pwr_cl_ddr_52_360 ==
668 bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360])); 682 bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) &&
683 (card->ext_csd.raw_pwr_cl_ddr_200_360 ==
684 bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360]));
685
669 if (err) 686 if (err)
670 err = -EINVAL; 687 err = -EINVAL;
671 688
@@ -768,7 +785,9 @@ static int __mmc_select_powerclass(struct mmc_card *card,
768 ext_csd->raw_pwr_cl_52_360 : 785 ext_csd->raw_pwr_cl_52_360 :
769 ext_csd->raw_pwr_cl_ddr_52_360; 786 ext_csd->raw_pwr_cl_ddr_52_360;
770 else if (host->ios.clock <= MMC_HS200_MAX_DTR) 787 else if (host->ios.clock <= MMC_HS200_MAX_DTR)
771 pwrclass_val = ext_csd->raw_pwr_cl_200_360; 788 pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ?
789 ext_csd->raw_pwr_cl_ddr_200_360 :
790 ext_csd->raw_pwr_cl_200_360;
772 break; 791 break;
773 default: 792 default:
774 pr_warning("%s: Voltage range not supported " 793 pr_warning("%s: Voltage range not supported "
@@ -832,7 +851,8 @@ static void mmc_set_bus_speed(struct mmc_card *card)
832{ 851{
833 unsigned int max_dtr = (unsigned int)-1; 852 unsigned int max_dtr = (unsigned int)-1;
834 853
835 if (mmc_card_hs200(card) && max_dtr > card->ext_csd.hs200_max_dtr) 854 if ((mmc_card_hs200(card) || mmc_card_hs400(card)) &&
855 max_dtr > card->ext_csd.hs200_max_dtr)
836 max_dtr = card->ext_csd.hs200_max_dtr; 856 max_dtr = card->ext_csd.hs200_max_dtr;
837 else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr) 857 else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr)
838 max_dtr = card->ext_csd.hs_max_dtr; 858 max_dtr = card->ext_csd.hs_max_dtr;
@@ -985,6 +1005,61 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
985 return err; 1005 return err;
986} 1006}
987 1007
1008static int mmc_select_hs400(struct mmc_card *card)
1009{
1010 struct mmc_host *host = card->host;
1011 int err = 0;
1012
1013 /*
1014 * HS400 mode requires 8-bit bus width
1015 */
1016 if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
1017 host->ios.bus_width == MMC_BUS_WIDTH_8))
1018 return 0;
1019
1020 /*
1021 * Before switching to dual data rate operation for HS400,
1022 * it is required to convert from HS200 mode to HS mode.
1023 */
1024 mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
1025 mmc_set_bus_speed(card);
1026
1027 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1028 EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
1029 card->ext_csd.generic_cmd6_time,
1030 true, true, true);
1031 if (err) {
1032 pr_warn("%s: switch to high-speed from hs200 failed, err:%d\n",
1033 mmc_hostname(host), err);
1034 return err;
1035 }
1036
1037 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1038 EXT_CSD_BUS_WIDTH,
1039 EXT_CSD_DDR_BUS_WIDTH_8,
1040 card->ext_csd.generic_cmd6_time);
1041 if (err) {
1042 pr_warn("%s: switch to bus width for hs400 failed, err:%d\n",
1043 mmc_hostname(host), err);
1044 return err;
1045 }
1046
1047 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1048 EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400,
1049 card->ext_csd.generic_cmd6_time,
1050 true, true, true);
1051 if (err) {
1052 pr_warn("%s: switch to hs400 failed, err:%d\n",
1053 mmc_hostname(host), err);
1054 return err;
1055 }
1056
1057 mmc_set_timing(host, MMC_TIMING_MMC_HS400);
1058 mmc_set_bus_speed(card);
1059
1060 return 0;
1061}
1062
988/* 1063/*
989 * For device supporting HS200 mode, the following sequence 1064 * For device supporting HS200 mode, the following sequence
990 * should be done before executing the tuning process. 1065 * should be done before executing the tuning process.
@@ -1062,13 +1137,22 @@ bus_speed:
1062 1137
1063/* 1138/*
1064 * Execute tuning sequence to seek the proper bus operating 1139 * Execute tuning sequence to seek the proper bus operating
1065 * conditions for HS200, which sends CMD21 to the device. 1140 * conditions for HS200 and HS400, which sends CMD21 to the device.
1066 */ 1141 */
1067static int mmc_hs200_tuning(struct mmc_card *card) 1142static int mmc_hs200_tuning(struct mmc_card *card)
1068{ 1143{
1069 struct mmc_host *host = card->host; 1144 struct mmc_host *host = card->host;
1070 int err = 0; 1145 int err = 0;
1071 1146
1147 /*
1148 * Timing should be adjusted to the HS400 target
1149 * operation frequency for tuning process
1150 */
1151 if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
1152 host->ios.bus_width == MMC_BUS_WIDTH_8)
1153 if (host->ops->prepare_hs400_tuning)
1154 host->ops->prepare_hs400_tuning(host, &host->ios);
1155
1072 if (host->ops->execute_tuning) { 1156 if (host->ops->execute_tuning) {
1073 mmc_host_clk_hold(host); 1157 mmc_host_clk_hold(host);
1074 err = host->ops->execute_tuning(host, 1158 err = host->ops->execute_tuning(host,
@@ -1296,6 +1380,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
1296 err = mmc_hs200_tuning(card); 1380 err = mmc_hs200_tuning(card);
1297 if (err) 1381 if (err)
1298 goto err; 1382 goto err;
1383
1384 err = mmc_select_hs400(card);
1385 if (err)
1386 goto err;
1299 } else if (mmc_card_hs(card)) { 1387 } else if (mmc_card_hs(card)) {
1300 /* Select the desired bus width optionally */ 1388 /* Select the desired bus width optionally */
1301 err = mmc_select_bus_width(card); 1389 err = mmc_select_bus_width(card);
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 176073692872..d424b9de3aff 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -110,6 +110,7 @@ struct mmc_ext_csd {
110 u8 raw_pwr_cl_200_360; /* 237 */ 110 u8 raw_pwr_cl_200_360; /* 237 */
111 u8 raw_pwr_cl_ddr_52_195; /* 238 */ 111 u8 raw_pwr_cl_ddr_52_195; /* 238 */
112 u8 raw_pwr_cl_ddr_52_360; /* 239 */ 112 u8 raw_pwr_cl_ddr_52_360; /* 239 */
113 u8 raw_pwr_cl_ddr_200_360; /* 253 */
113 u8 raw_bkops_status; /* 246 */ 114 u8 raw_bkops_status; /* 246 */
114 u8 raw_sectors[4]; /* 212 - 4 bytes */ 115 u8 raw_sectors[4]; /* 212 - 4 bytes */
115 116
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 6b1e9ee6ca10..183087374215 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -61,6 +61,7 @@ struct mmc_ios {
61#define MMC_TIMING_UHS_DDR50 7 61#define MMC_TIMING_UHS_DDR50 7
62#define MMC_TIMING_MMC_DDR52 8 62#define MMC_TIMING_MMC_DDR52 8
63#define MMC_TIMING_MMC_HS200 9 63#define MMC_TIMING_MMC_HS200 9
64#define MMC_TIMING_MMC_HS400 10
64 65
65 unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ 66 unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */
66 67
@@ -132,6 +133,9 @@ struct mmc_host_ops {
132 133
133 /* The tuning command opcode value is different for SD and eMMC cards */ 134 /* The tuning command opcode value is different for SD and eMMC cards */
134 int (*execute_tuning)(struct mmc_host *host, u32 opcode); 135 int (*execute_tuning)(struct mmc_host *host, u32 opcode);
136
137 /* Prepare HS400 target operating frequency depending host driver */
138 int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
135 int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); 139 int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
136 void (*hw_reset)(struct mmc_host *host); 140 void (*hw_reset)(struct mmc_host *host);
137 void (*card_event)(struct mmc_host *host); 141 void (*card_event)(struct mmc_host *host);
@@ -274,6 +278,10 @@ struct mmc_host {
274#define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ 278#define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \
275 MMC_CAP2_PACKED_WR) 279 MMC_CAP2_PACKED_WR)
276#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ 280#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */
281#define MMC_CAP2_HS400_1_8V (1 << 15) /* Can support HS400 1.8V */
282#define MMC_CAP2_HS400_1_2V (1 << 16) /* Can support HS400 1.2V */
283#define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V | \
284 MMC_CAP2_HS400_1_2V)
277 285
278 mmc_pm_flag_t pm_caps; /* supported pm features */ 286 mmc_pm_flag_t pm_caps; /* supported pm features */
279 287
@@ -495,4 +503,10 @@ static inline bool mmc_card_ddr52(struct mmc_card *card)
495{ 503{
496 return card->host->ios.timing == MMC_TIMING_MMC_DDR52; 504 return card->host->ios.timing == MMC_TIMING_MMC_DDR52;
497} 505}
506
507static inline bool mmc_card_hs400(struct mmc_card *card)
508{
509 return card->host->ios.timing == MMC_TIMING_MMC_HS400;
510}
511
498#endif /* LINUX_MMC_HOST_H */ 512#endif /* LINUX_MMC_HOST_H */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index f429f13be433..64ec963ed347 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -325,6 +325,7 @@ struct _mmc_csd {
325#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ 325#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
326#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ 326#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
327#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ 327#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
328#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
328#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ 329#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
329#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ 330#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
330#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */ 331#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
@@ -354,7 +355,6 @@ struct _mmc_csd {
354#define EXT_CSD_CMD_SET_SECURE (1<<1) 355#define EXT_CSD_CMD_SET_SECURE (1<<1)
355#define EXT_CSD_CMD_SET_CPSECURE (1<<2) 356#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
356 357
357#define EXT_CSD_CARD_TYPE_MASK 0x3F /* Mask out reserved bits */
358#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */ 358#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
359#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */ 359#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
360#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \ 360#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
@@ -370,6 +370,10 @@ struct _mmc_csd {
370 /* SDR mode @1.2V I/O */ 370 /* SDR mode @1.2V I/O */
371#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \ 371#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
372 EXT_CSD_CARD_TYPE_HS200_1_2V) 372 EXT_CSD_CARD_TYPE_HS200_1_2V)
373#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
374#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
375#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
376 EXT_CSD_CARD_TYPE_HS400_1_2V)
373 377
374#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ 378#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
375#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ 379#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
@@ -380,6 +384,7 @@ struct _mmc_csd {
380#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */ 384#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
381#define EXT_CSD_TIMING_HS 1 /* High speed */ 385#define EXT_CSD_TIMING_HS 1 /* High speed */
382#define EXT_CSD_TIMING_HS200 2 /* HS200 */ 386#define EXT_CSD_TIMING_HS200 2 /* HS200 */
387#define EXT_CSD_TIMING_HS400 3 /* HS400 */
383 388
384#define EXT_CSD_SEC_ER_EN BIT(0) 389#define EXT_CSD_SEC_ER_EN BIT(0)
385#define EXT_CSD_SEC_BD_BLK_EN BIT(2) 390#define EXT_CSD_SEC_BD_BLK_EN BIT(2)