diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 2170094c03..e2c3c86d96 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1511,6 +1511,10 @@ static int mmc_startup(struct mmc *mmc) #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT) init_part(&mmc->block_dev); #endif + /* Add device specific quirks */ + if (((mmc->cid[0] & MMC_MID_MASK) == MMC_MID_SANDISK) && + (strncmp(mmc->block_dev.product, "SEM08", 5) == 0)) + mmc->quirks |= MMC_QUIRK_SECURE_TRIM; return 0; } diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index 66e4c1675f..c03b0943c1 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -140,25 +140,38 @@ unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt) return blk; } else { - err = mmc_erase_t(mmc, start, blkcnt, arg); + if ( mmc->quirks & MMC_QUIRK_SECURE_TRIM ) { + arg = MMC_TRIM_ARG; + err = mmc_erase_t(mmc, start, blkcnt, arg); - if (err) - return -1; + if (err) + return -1; - /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) - return -1; + /* Waiting for the ready status */ + if (mmc_send_status(mmc, timeout)) + return -1; + } else { + err = mmc_erase_t(mmc, start, blkcnt, arg); - arg = MMC_SECURE_TRIM2_ARG; - err = mmc_erase_t(mmc, start, blkcnt, arg); + if (err) + return -1; - if (err) - return -1; + /* Waiting for the ready status */ + if (mmc_send_status(mmc, timeout)) + return -1; - /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) { - return 0; + arg = MMC_SECURE_TRIM2_ARG; + err = mmc_erase_t(mmc, start, blkcnt, arg); + + if (err) + return -1; + + /* Waiting for the ready status */ + if (mmc_send_status(mmc, timeout)) { + return 0; + } } + return blkcnt; } diff --git a/include/mmc.h b/include/mmc.h index 6c4b3c1af8..68bd128bf4 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -299,6 +299,16 @@ /* Driver model support */ +#define MMC_MID_MASK (0xFF << 24) +#define MMC_MID_SANDISK (0x45 << 24) + +/* + * Quirks + */ +/* Some of Sandisk eMMC seeing more delay for secure trim, + * below quirk will use trim instead secure trim for erase */ +#define MMC_QUIRK_SECURE_TRIM (1 << 0) + /** * struct mmc_uclass_priv - Holds information about a device used by the uclass */ @@ -416,6 +426,7 @@ struct mmc { int ddr_mode; uchar sec_feature_support; unsigned int trim_timeout; /* In milliseconds */ + u32 quirks; }; struct mmc_hwpart_conf {