Hi Haijun, On Dec 10, 2013, at 7:39 AM, Haijun Zhang wrote:
> Read command class from csd register and secure erase > support bit from ext csd register. Also calculate the erase > timeout and secure erase timeout. > > If read ext csd error, error status should be returned instead of > give some incorrect information. > s/give some/giving/ > Error log: > => > => mmcinfo > Device: FSL_SDHC > Manufacturer ID: 0 > OEM: 0 > Name: Tran Speed: 0 > Rd Block Len: 0 > MMC version 0.0 > High Capacity: No > Capacity: 0 Bytes > Bus Width: 1-bit > => > > Signed-off-by: Haijun Zhang <haijun.zh...@freescale.com> > --- > changes for V3: > - Change the erase group size to be block aligned. > > drivers/mmc/mmc.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- > 1 file changed, 38 insertions(+), 14 deletions(-) > > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c > index e1461a9..e8dbb8c 100644 > --- a/drivers/mmc/mmc.c > +++ b/drivers/mmc/mmc.c > @@ -871,6 +871,8 @@ static int mmc_startup(struct mmc *mmc) > } > } > > + mmc->cmdclass = cmd.response[1] >> 20; > + ^ use mask of cmd class maximum width (even if class is 12 bit wide) > /* divide frequency by 10, since the mults are 10x bigger */ > freq = fbase[(cmd.response[0] & 0x7)]; > mult = multipliers[((cmd.response[0] >> 3) & 0xf)]; > @@ -939,7 +941,8 @@ static int mmc_startup(struct mmc *mmc) > capacity *= MMC_MAX_BLOCK_LEN; > if ((capacity >> 20) > 2 * 1024) > mmc->capacity_user = capacity; > - } > + } else > + return COMM_ERR; > > switch (ext_csd[EXT_CSD_REV]) { > case 1: > @@ -960,6 +963,39 @@ static int mmc_startup(struct mmc *mmc) > } > > /* > + * The granularity of the erasable units is the Erase Group:The > + * smallest number of consecutive write blocks which can be > + * addressed for erase. The size of the Erase Group is card > + * specific and stored in the CSD when ERASE_GROUP_DEF is > + * disabled, and in the EXT_CSD when ERASE_GROUP_DEF is > + * enabled. > + */ > + if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) { > + mmc->erase_grp_size = > + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024; > + > + mmc->erase_timeout_mult = 300 * > + ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; > + } else { > + /* Calculate the group size from the csd value. */ > + int erase_gsz, erase_gmul; > + erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10; > + erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; > + mmc->erase_grp_size = (erase_gsz + 1) > + * (erase_gmul + 1); > + } > + > + if (ext_csd[EXT_CSD_REV] >= 4) { > + mmc->sec_feature_support = > + ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; > + mmc->sec_erase_mult = > + ext_csd[EXT_CSD_SEC_ERASE_MULT]; > + mmc->sec_erase_timeout = 300 * > + ext_csd[EXT_CSD_SEC_ERASE_MULT] * > + ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; > + } > + > + /* > * Host needs to enable ERASE_GRP_DEF bit if device is > * partitioned. This bit will be lost every time after a reset > * or power off. This will affect erase size. > @@ -968,23 +1004,11 @@ static int mmc_startup(struct mmc *mmc) > (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) { > err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, > EXT_CSD_ERASE_GROUP_DEF, 1); > - ^ removed line for no reason > if (err) > return err; > - > - /* Read out group size from ext_csd */ > - mmc->erase_grp_size = > - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * > - MMC_MAX_BLOCK_LEN * 1024; > - } else { > - /* Calculate the group size from the csd value. */ > - int erase_gsz, erase_gmul; > - erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10; > - erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; > - mmc->erase_grp_size = (erase_gsz + 1) > - * (erase_gmul + 1); > } > > + ^ extra line > /* store the partition info of emmc */ > if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || > ext_csd[EXT_CSD_BOOT_MULT]) > -- > 1.8.4.1 > > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot