hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
u-boot/drivers/mmc/mmc.c
....@@ -1007,12 +1007,22 @@
10071007 return ret;
10081008 }
10091009
1010
+static int mmc_switch_to_hs400(struct mmc *mmc)
1011
+{
1012
+ u8 val, fixed_drv_type, card_drv_type, drive_strength;
1013
+
1014
+ fixed_drv_type = mmc->cfg->fixed_drv_type;
1015
+ card_drv_type = mmc->raw_driver_strength | mmc_driver_type_mask(0);
1016
+ drive_strength = (card_drv_type & mmc_driver_type_mask(fixed_drv_type))
1017
+ ? fixed_drv_type : 0;
1018
+ val = EXT_CSD_TIMING_HS400 | drive_strength << EXT_CSD_DRV_STR_SHIFT;
1019
+
1020
+ return __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, val, false);
1021
+}
1022
+
10101023 static int mmc_select_hs400(struct mmc *mmc)
10111024 {
10121025 int ret;
1013
-
1014
- /* Reduce frequency to HS frequency */
1015
- mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
10161026
10171027 /* Switch card to HS mode */
10181028 ret = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
....@@ -1022,6 +1032,9 @@
10221032
10231033 /* Set host controller to HS timing */
10241034 mmc_set_timing(mmc, MMC_TIMING_MMC_HS);
1035
+
1036
+ /* Reduce frequency to HS frequency */
1037
+ mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
10251038
10261039 ret = mmc_send_status(mmc, 1000);
10271040 if (ret)
....@@ -1035,8 +1048,7 @@
10351048 return ret;
10361049
10371050 /* Switch card to HS400 */
1038
- ret = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1039
- EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, false);
1051
+ ret = mmc_switch_to_hs400(mmc);
10401052 if (ret)
10411053 return ret;
10421054
....@@ -1045,9 +1057,48 @@
10451057
10461058 return ret;
10471059 }
1060
+
1061
+static int mmc_select_hs400es(struct mmc *mmc)
1062
+{
1063
+ int err;
1064
+
1065
+ /* Switch card to HS mode */
1066
+ err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1067
+ EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, false);
1068
+ if (err)
1069
+ return err;
1070
+
1071
+ /* Set host controller to HS timing */
1072
+ mmc_set_timing(mmc, MMC_TIMING_MMC_HS);
1073
+
1074
+ err = mmc_send_status(mmc, 1000);
1075
+ if (err)
1076
+ return err;
1077
+
1078
+ mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
1079
+
1080
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
1081
+ EXT_CSD_DDR_BUS_WIDTH_8 |
1082
+ EXT_CSD_BUS_WIDTH_STROBE);
1083
+ if (err) {
1084
+ printf("switch to bus width for hs400 failed\n");
1085
+ return err;
1086
+ }
1087
+
1088
+ /* Switch card to HS400 */
1089
+ err = mmc_switch_to_hs400(mmc);
1090
+ if (err)
1091
+ return err;
1092
+
1093
+ /* Set host controller to HS400 timing and frequency */
1094
+ mmc_set_timing(mmc, MMC_TIMING_MMC_HS400ES);
1095
+
1096
+ return mmc_set_enhanced_strobe(mmc);
1097
+}
10481098 #else
10491099 static int mmc_select_hs200(struct mmc *mmc) { return 0; }
10501100 static int mmc_select_hs400(struct mmc *mmc) { return 0; }
1101
+static int mmc_select_hs400es(struct mmc *mmc) { return 0; }
10511102 #endif
10521103
10531104 static u32 mmc_select_card_type(struct mmc *mmc, u8 *ext_csd)
....@@ -1139,6 +1190,16 @@
11391190 return err;
11401191
11411192 avail_type = mmc_select_card_type(mmc, ext_csd);
1193
+
1194
+ if (avail_type & EXT_CSD_CARD_TYPE_HS400ES) {
1195
+ err = mmc_select_bus_width(mmc);
1196
+ if (err > 0 && mmc->bus_width == MMC_BUS_WIDTH_8BIT) {
1197
+ err = mmc_select_hs400es(mmc);
1198
+ mmc_set_bus_speed(mmc, avail_type);
1199
+ if (!err)
1200
+ return err;
1201
+ }
1202
+ }
11421203
11431204 if (avail_type & EXT_CSD_CARD_TYPE_HS200)
11441205 err = mmc_select_hs200(mmc);
....@@ -1824,6 +1885,10 @@
18241885 mmc->erase_grp_size = 1;
18251886 mmc->part_config = MMCPART_NOAVAILABLE;
18261887 if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
1888
+ /* select high speed to reduce initialization time */
1889
+ mmc_select_hs(mmc);
1890
+ mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
1891
+
18271892 /* check ext_csd version and capacity */
18281893 err = mmc_send_ext_csd(mmc, ext_csd);
18291894 if (err)
....@@ -1973,6 +2038,8 @@
19732038 * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
19742039
19752040 mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
2041
+
2042
+ mmc->raw_driver_strength = ext_csd[EXT_CSD_DRIVER_STRENGTH];
19762043 }
19772044
19782045 err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);