]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
mmc: When switching partition, use the timeout specified in the ext_csd
authorJean-Jacques Hiblot <jjhiblot@ti.com>
Tue, 2 Jul 2019 08:53:55 +0000 (10:53 +0200)
committerPeng Fan <peng.fan@nxp.com>
Mon, 15 Jul 2019 02:16:49 +0000 (10:16 +0800)
The e-MMC spec allows the e-MMC to specify a timeout for the partition
switch command. It can take up to 2550 ms. There is no lower limit to this
value in the spec, but do as the the linux driver does and force it to be
at least 300ms.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
drivers/mmc/mmc.c
include/mmc.h

index ff56c3dd67dd361a6a934364c2df13ac109c25f6..e5cee7dbc888715791924d74cfd362d186e20144 100644 (file)
@@ -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) ||
index 711cb5d116d1199935bc26d753958bbaf70a4fe8..032873c2ff9b43266a138087dfa2a440bb873cb3 100644 (file)
@@ -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