mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
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:
parent
d8973d0871
commit
cad4eba461
3 changed files with 59 additions and 11 deletions
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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,26 +87,59 @@ 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, arg);
|
||||
|
||||
if (err)
|
||||
break;
|
||||
|
||||
blk += blk_r;
|
||||
|
||||
/* Waiting for the ready status */
|
||||
if (mmc_send_status(mmc, timeout))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return blk;
|
||||
} else {
|
||||
err = mmc_erase_t(mmc, start, blkcnt, 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);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
blk += blk_r;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue