.. | .. |
---|
1007 | 1007 | return ret; |
---|
1008 | 1008 | } |
---|
1009 | 1009 | |
---|
| 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 | + |
---|
1010 | 1023 | static int mmc_select_hs400(struct mmc *mmc) |
---|
1011 | 1024 | { |
---|
1012 | 1025 | int ret; |
---|
1013 | | - |
---|
1014 | | - /* Reduce frequency to HS frequency */ |
---|
1015 | | - mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR); |
---|
1016 | 1026 | |
---|
1017 | 1027 | /* Switch card to HS mode */ |
---|
1018 | 1028 | ret = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, |
---|
.. | .. |
---|
1022 | 1032 | |
---|
1023 | 1033 | /* Set host controller to HS timing */ |
---|
1024 | 1034 | 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); |
---|
1025 | 1038 | |
---|
1026 | 1039 | ret = mmc_send_status(mmc, 1000); |
---|
1027 | 1040 | if (ret) |
---|
.. | .. |
---|
1035 | 1048 | return ret; |
---|
1036 | 1049 | |
---|
1037 | 1050 | /* 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); |
---|
1040 | 1052 | if (ret) |
---|
1041 | 1053 | return ret; |
---|
1042 | 1054 | |
---|
.. | .. |
---|
1045 | 1057 | |
---|
1046 | 1058 | return ret; |
---|
1047 | 1059 | } |
---|
| 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 | +} |
---|
1048 | 1098 | #else |
---|
1049 | 1099 | static int mmc_select_hs200(struct mmc *mmc) { return 0; } |
---|
1050 | 1100 | static int mmc_select_hs400(struct mmc *mmc) { return 0; } |
---|
| 1101 | +static int mmc_select_hs400es(struct mmc *mmc) { return 0; } |
---|
1051 | 1102 | #endif |
---|
1052 | 1103 | |
---|
1053 | 1104 | static u32 mmc_select_card_type(struct mmc *mmc, u8 *ext_csd) |
---|
.. | .. |
---|
1139 | 1190 | return err; |
---|
1140 | 1191 | |
---|
1141 | 1192 | 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 | + } |
---|
1142 | 1203 | |
---|
1143 | 1204 | if (avail_type & EXT_CSD_CARD_TYPE_HS200) |
---|
1144 | 1205 | err = mmc_select_hs200(mmc); |
---|
.. | .. |
---|
1824 | 1885 | mmc->erase_grp_size = 1; |
---|
1825 | 1886 | mmc->part_config = MMCPART_NOAVAILABLE; |
---|
1826 | 1887 | 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 | + |
---|
1827 | 1892 | /* check ext_csd version and capacity */ |
---|
1828 | 1893 | err = mmc_send_ext_csd(mmc, ext_csd); |
---|
1829 | 1894 | if (err) |
---|
.. | .. |
---|
1973 | 2038 | * ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; |
---|
1974 | 2039 | |
---|
1975 | 2040 | mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; |
---|
| 2041 | + |
---|
| 2042 | + mmc->raw_driver_strength = ext_csd[EXT_CSD_DRIVER_STRENGTH]; |
---|
1976 | 2043 | } |
---|
1977 | 2044 | |
---|
1978 | 2045 | err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart); |
---|