mmc: eMMC add Secured Trim command support

Secured Trim command does eMMC erase for  unalligned block size.

Change-Id: I4dc7bea15c8fcb57e07d19c398b1c8e2289da100
Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
This commit is contained in:
Sham Muthayyan 2017-03-09 19:52:24 +05:30 committed by Gerrit - the friendly Code Review server
parent d8973d0871
commit cad4eba461
3 changed files with 59 additions and 11 deletions

View file

@ -1231,6 +1231,9 @@ static int mmc_startup(struct mmc *mmc)
if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
ext_csd[EXT_CSD_BOOT_MULT])
mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
if(ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT])
mmc->sec_feature_support = ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
if (part_completed &&
(ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];

View file

@ -14,7 +14,7 @@
#include <linux/math64.h>
#include "mmc_private.h"
static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, int arg)
{
struct mmc_cmd cmd;
ulong end;
@ -51,7 +51,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
goto err_out;
cmd.cmdidx = MMC_CMD_ERASE;
cmd.cmdarg = MMC_ERASE_ARG;
cmd.cmdarg = arg;
cmd.resp_type = MMC_RSP_R1b;
err = mmc_send_cmd(mmc, &cmd, NULL);
@ -71,11 +71,15 @@ unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
u32 start_rem, blkcnt_rem;
struct mmc *mmc = find_mmc_device(dev_num);
lbaint_t blk = 0, blk_r = 0;
int timeout = 1000;
int timeout = 2000;
int arg = MMC_ERASE_ARG;
if (!mmc)
return -1;
if (!(mmc->sec_feature_support & EXT_CSD_SEC_ER_EN)) {
return -1;
}
/*
* We want to see if the requested start or total block count are
* unaligned. We discard the whole numbers and only care about the
@ -83,18 +87,27 @@ unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
*/
err = div_u64_rem(start, mmc->erase_grp_size, &start_rem);
err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem);
if (start_rem || blkcnt_rem)
if (start_rem || blkcnt_rem) {
if (mmc->sec_feature_support & EXT_CSD_SEC_GB_CL_EN) {
arg = MMC_SECURE_TRIM1_ARG;
} else {
printf("\n\nCaution! Your devices Erase group is 0x%x\n"
"The erase range would be change to "
"0x" LBAF "~0x" LBAF "\n\n",
mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
((start + blkcnt + mmc->erase_grp_size)
& ~(mmc->erase_grp_size - 1)) - 1);
}
}
if (arg != MMC_SECURE_TRIM1_ARG) {
while (blk < blkcnt) {
blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
mmc->erase_grp_size : (blkcnt - blk);
err = mmc_erase_t(mmc, start + blk, blk_r);
err = mmc_erase_t(mmc, start + blk, blk_r, arg);
if (err)
break;
@ -105,6 +118,30 @@ unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
return 0;
}
return blk;
} else {
err = mmc_erase_t(mmc, start, blkcnt, arg);
if (err)
return -1;
/* Waiting for the ready status */
if (mmc_send_status(mmc, timeout))
return -1;
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;
}
return blk;
}

View file

@ -191,7 +191,10 @@
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_MULT 226 /* RO */
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
#define EXT_CSD_SEC_ER_EN (1 << 0)
#define EXT_CSD_SEC_GB_CL_EN (1 << 4)
/*
* EXT_CSD field definitions
*/
@ -293,6 +296,10 @@ struct mmc *mmc_get_mmc_dev(struct udevice *dev);
/* End of driver model support */
#define MMC_SECURE_TRIM1_ARG 0x80000001
#define MMC_SECURE_TRIM2_ARG 0x80008000
struct mmc_cid {
unsigned long psn;
unsigned short oid;
@ -382,6 +389,7 @@ struct mmc {
char init_in_progress; /* 1 if we have done mmc_start_init() */
char preinit; /* start init as early as possible */
int ddr_mode;
uchar sec_feature_support;
};
struct mmc_hwpart_conf {