diff options
-rw-r--r-- | drivers/mmc/mmc.c | 10 | ||||
-rw-r--r-- | include/mmc.h | 5 |
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ff56c3dd67d..e5cee7dbc88 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -748,12 +748,17 @@ static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value, { struct mmc_cmd cmd; int timeout = DEFAULT_CMD6_TIMEOUT_MS; + bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) && + (index == EXT_CSD_PART_CONF); int retries = 3; int ret; if (mmc->gen_cmd6_time) timeout = mmc->gen_cmd6_time * 10; + if (is_part_switch && mmc->part_switch_time) + timeout = mmc->part_switch_time * 10; + cmd.cmdidx = MMC_CMD_SWITCH; cmd.resp_type = MMC_RSP_R1b; cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | @@ -2152,6 +2157,11 @@ static int mmc_startup_v4(struct mmc *mmc) part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] & EXT_CSD_PARTITION_SETTING_COMPLETED); + mmc->part_switch_time = ext_csd[EXT_CSD_PART_SWITCH_TIME]; + /* Some eMMC set the value too low so set a minimum */ + if (mmc->part_switch_time < MMC_MIN_PART_SWITCH_TIME && mmc->part_switch_time) + mmc->part_switch_time = MMC_MIN_PART_SWITCH_TIME; + /* store the partition info of emmc */ mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT]; if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || diff --git a/include/mmc.h b/include/mmc.h index 711cb5d116d..032873c2ff9 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -226,6 +226,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_CARD_TYPE 196 /* RO */ +#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ @@ -587,6 +588,7 @@ struct mmc { u8 wr_rel_set; u8 part_config; u8 gen_cmd6_time; + u8 part_switch_time; uint tran_speed; uint legacy_speed; /* speed for the legacy mode provided by the card */ uint read_bl_len; @@ -833,6 +835,9 @@ extern uint mmc_get_env_part(struct mmc *mmc); # endif int mmc_get_env_dev(void); +/* Minimum partition switch timeout in units of 10-milliseconds */ +#define MMC_MIN_PART_SWITCH_TIME 30 /* 300 ms */ + /* Set block count limit because of 16 bit register limit on some hardware*/ #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT #define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535 |