Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Seungwon Jeon and committed by
Chris Ball
0a5b6438 577fb131

+118 -6
+1
drivers/mmc/core/bus.c
··· 349 349 mmc_hostname(card->host), 350 350 mmc_card_uhs(card) ? "ultra high speed " : 351 351 (mmc_card_hs(card) ? "high speed " : ""), 352 + mmc_card_hs400(card) ? "HS400 " : 352 353 (mmc_card_hs200(card) ? "HS200 " : ""), 353 354 mmc_card_ddr52(card) ? "DDR " : "", 354 355 uhs_bus_speed_mode, type, card->rca);
+3
drivers/mmc/core/debugfs.c
··· 141 141 case MMC_TIMING_MMC_HS200: 142 142 str = "mmc HS200"; 143 143 break; 144 + case MMC_TIMING_MMC_HS400: 145 + str = "mmc HS400"; 146 + break; 144 147 default: 145 148 str = "invalid"; 146 149 break;
+93 -5
drivers/mmc/core/mmc.c
··· 240 240 static void mmc_select_card_type(struct mmc_card *card) 241 241 { 242 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 244 u32 caps = host->caps, caps2 = host->caps2; 245 245 unsigned int hs_max_dtr = 0, hs200_max_dtr = 0; 246 246 unsigned int avail_type = 0; ··· 279 279 card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) { 280 280 hs200_max_dtr = MMC_HS200_MAX_DTR; 281 281 avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V; 282 + } 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; 282 294 } 283 295 284 296 card->ext_csd.hs_max_dtr = hs_max_dtr; ··· 511 499 ext_csd[EXT_CSD_PWR_CL_DDR_52_195]; 512 500 card->ext_csd.raw_pwr_cl_ddr_52_360 = 513 501 ext_csd[EXT_CSD_PWR_CL_DDR_52_360]; 502 + card->ext_csd.raw_pwr_cl_ddr_200_360 = 503 + ext_csd[EXT_CSD_PWR_CL_DDR_200_360]; 514 504 } 515 505 516 506 if (card->ext_csd.rev >= 5) { ··· 679 665 (card->ext_csd.raw_pwr_cl_ddr_52_195 == 680 666 bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) && 681 667 (card->ext_csd.raw_pwr_cl_ddr_52_360 == 682 - bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360])); 668 + bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) && 669 + (card->ext_csd.raw_pwr_cl_ddr_200_360 == 670 + bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360])); 671 + 683 672 if (err) 684 673 err = -EINVAL; 685 674 ··· 785 768 ext_csd->raw_pwr_cl_52_360 : 786 769 ext_csd->raw_pwr_cl_ddr_52_360; 787 770 else if (host->ios.clock <= MMC_HS200_MAX_DTR) 788 - pwrclass_val = ext_csd->raw_pwr_cl_200_360; 771 + pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ? 772 + ext_csd->raw_pwr_cl_ddr_200_360 : 773 + ext_csd->raw_pwr_cl_200_360; 789 774 break; 790 775 default: 791 776 pr_warning("%s: Voltage range not supported " ··· 851 832 { 852 833 unsigned int max_dtr = (unsigned int)-1; 853 834 854 - if (mmc_card_hs200(card) && max_dtr > card->ext_csd.hs200_max_dtr) 835 + if ((mmc_card_hs200(card) || mmc_card_hs400(card)) && 836 + max_dtr > card->ext_csd.hs200_max_dtr) 855 837 max_dtr = card->ext_csd.hs200_max_dtr; 856 838 else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr) 857 839 max_dtr = card->ext_csd.hs_max_dtr; ··· 1005 985 return err; 1006 986 } 1007 987 988 + static int mmc_select_hs400(struct mmc_card *card) 989 + { 990 + struct mmc_host *host = card->host; 991 + int err = 0; 992 + 993 + /* 994 + * HS400 mode requires 8-bit bus width 995 + */ 996 + if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && 997 + host->ios.bus_width == MMC_BUS_WIDTH_8)) 998 + return 0; 999 + 1000 + /* 1001 + * Before switching to dual data rate operation for HS400, 1002 + * it is required to convert from HS200 mode to HS mode. 1003 + */ 1004 + mmc_set_timing(card->host, MMC_TIMING_MMC_HS); 1005 + mmc_set_bus_speed(card); 1006 + 1007 + err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1008 + EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, 1009 + card->ext_csd.generic_cmd6_time, 1010 + true, true, true); 1011 + if (err) { 1012 + pr_warn("%s: switch to high-speed from hs200 failed, err:%d\n", 1013 + mmc_hostname(host), err); 1014 + return err; 1015 + } 1016 + 1017 + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1018 + EXT_CSD_BUS_WIDTH, 1019 + EXT_CSD_DDR_BUS_WIDTH_8, 1020 + card->ext_csd.generic_cmd6_time); 1021 + if (err) { 1022 + pr_warn("%s: switch to bus width for hs400 failed, err:%d\n", 1023 + mmc_hostname(host), err); 1024 + return err; 1025 + } 1026 + 1027 + err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1028 + EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, 1029 + card->ext_csd.generic_cmd6_time, 1030 + true, true, true); 1031 + if (err) { 1032 + pr_warn("%s: switch to hs400 failed, err:%d\n", 1033 + mmc_hostname(host), err); 1034 + return err; 1035 + } 1036 + 1037 + mmc_set_timing(host, MMC_TIMING_MMC_HS400); 1038 + mmc_set_bus_speed(card); 1039 + 1040 + return 0; 1041 + } 1042 + 1008 1043 /* 1009 1044 * For device supporting HS200 mode, the following sequence 1010 1045 * should be done before executing the tuning process. ··· 1137 1062 1138 1063 /* 1139 1064 * Execute tuning sequence to seek the proper bus operating 1140 - * conditions for HS200, which sends CMD21 to the device. 1065 + * conditions for HS200 and HS400, which sends CMD21 to the device. 1141 1066 */ 1142 1067 static int mmc_hs200_tuning(struct mmc_card *card) 1143 1068 { 1144 1069 struct mmc_host *host = card->host; 1145 1070 int err = 0; 1071 + 1072 + /* 1073 + * Timing should be adjusted to the HS400 target 1074 + * operation frequency for tuning process 1075 + */ 1076 + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 && 1077 + host->ios.bus_width == MMC_BUS_WIDTH_8) 1078 + if (host->ops->prepare_hs400_tuning) 1079 + host->ops->prepare_hs400_tuning(host, &host->ios); 1146 1080 1147 1081 if (host->ops->execute_tuning) { 1148 1082 mmc_host_clk_hold(host); ··· 1378 1294 1379 1295 if (mmc_card_hs200(card)) { 1380 1296 err = mmc_hs200_tuning(card); 1297 + if (err) 1298 + goto err; 1299 + 1300 + err = mmc_select_hs400(card); 1381 1301 if (err) 1382 1302 goto err; 1383 1303 } else if (mmc_card_hs(card)) {
+1
include/linux/mmc/card.h
··· 110 110 u8 raw_pwr_cl_200_360; /* 237 */ 111 111 u8 raw_pwr_cl_ddr_52_195; /* 238 */ 112 112 u8 raw_pwr_cl_ddr_52_360; /* 239 */ 113 + u8 raw_pwr_cl_ddr_200_360; /* 253 */ 113 114 u8 raw_bkops_status; /* 246 */ 114 115 u8 raw_sectors[4]; /* 212 - 4 bytes */ 115 116
+14
include/linux/mmc/host.h
··· 61 61 #define MMC_TIMING_UHS_DDR50 7 62 62 #define MMC_TIMING_MMC_DDR52 8 63 63 #define MMC_TIMING_MMC_HS200 9 64 + #define MMC_TIMING_MMC_HS400 10 64 65 65 66 unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ 66 67 ··· 133 132 134 133 /* The tuning command opcode value is different for SD and eMMC cards */ 135 134 int (*execute_tuning)(struct mmc_host *host, u32 opcode); 135 + 136 + /* Prepare HS400 target operating frequency depending host driver */ 137 + int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios); 136 138 int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); 137 139 void (*hw_reset)(struct mmc_host *host); 138 140 void (*card_event)(struct mmc_host *host); ··· 278 274 #define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ 279 275 MMC_CAP2_PACKED_WR) 280 276 #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ 277 + #define MMC_CAP2_HS400_1_8V (1 << 15) /* Can support HS400 1.8V */ 278 + #define MMC_CAP2_HS400_1_2V (1 << 16) /* Can support HS400 1.2V */ 279 + #define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V | \ 280 + MMC_CAP2_HS400_1_2V) 281 281 282 282 mmc_pm_flag_t pm_caps; /* supported pm features */ 283 283 ··· 503 495 { 504 496 return card->host->ios.timing == MMC_TIMING_MMC_DDR52; 505 497 } 498 + 499 + static inline bool mmc_card_hs400(struct mmc_card *card) 500 + { 501 + return card->host->ios.timing == MMC_TIMING_MMC_HS400; 502 + } 503 + 506 504 #endif /* LINUX_MMC_HOST_H */
+6 -1
include/linux/mmc/mmc.h
··· 325 325 #define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ 326 326 #define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ 327 327 #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ 328 + #define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */ 328 329 #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ 329 330 #define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ 330 331 #define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */ ··· 355 354 #define EXT_CSD_CMD_SET_SECURE (1<<1) 356 355 #define EXT_CSD_CMD_SET_CPSECURE (1<<2) 357 356 358 - #define EXT_CSD_CARD_TYPE_MASK 0x3F /* Mask out reserved bits */ 359 357 #define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */ 360 358 #define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */ 361 359 #define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \ ··· 370 370 /* SDR mode @1.2V I/O */ 371 371 #define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \ 372 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 378 #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ 375 379 #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ ··· 384 380 #define EXT_CSD_TIMING_BC 0 /* Backwards compatility */ 385 381 #define EXT_CSD_TIMING_HS 1 /* High speed */ 386 382 #define EXT_CSD_TIMING_HS200 2 /* HS200 */ 383 + #define EXT_CSD_TIMING_HS400 3 /* HS400 */ 387 384 388 385 #define EXT_CSD_SEC_ER_EN BIT(0) 389 386 #define EXT_CSD_SEC_BD_BLK_EN BIT(2)