[U-Boot] [PATCH 1/7 V4] mmc: Add some usefull macro definition

From: Haijun Zhang Haijun.Zhang@freescale.com
Add command class define. Add mmc erase and secure erase define. Add secure erase and trim support bit define.
Signed-off-by: Haijun Zhang haijun.zhang@freescale.com --- changes for V4: - no changes changes for V3: - No changes
include/mmc.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/mmc.h b/include/mmc.h index cb558da..08f0f3e 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -53,6 +53,7 @@ #define COMM_ERR -18 /* Communications Error */ #define TIMEOUT -19 #define IN_PROGRESS -20 /* operation is in progress */ +#define NOT_SUPPORT -21 /* Operation is not support */
#define MMC_CMD_GO_IDLE_STATE 0 #define MMC_CMD_SEND_OP_COND 1 @@ -105,6 +106,39 @@ #define OCR_VOLTAGE_MASK 0x007FFF80 #define OCR_ACCESS_MODE 0x60000000
+/* + * Card Command Classes (CCC) + * + * (0) Basic protocol functions (CMD0,1,2,3,4,7,9,10,12,13,15) + * (and for SPI, CMD58,59) + * (1) Stream read commands (CMD11) + * (2) Block read commands (CMD16,17,18) + * (3) Stream write commands (CMD20) + * (4) Block write commands (CMD16,24,25,26,27) + * (5) Ability to erase blocks (CMD32,33,34,35,36,37,38,39) + * (6) Able to write protect blocks (CMD28,29,30) + * (7) Able to lock down card (CMD16,CMD42) + * (8) Application specific (CMD55,56,57,ACMD*) + * (9) I/O mode (CMD5,39,40,52,53) + * (10) High speed switch (CMD6,34,35,36,37,50) + */ +#define CCC_BASIC (1<<0) +#define CCC_STREAM_READ (1<<1) +#define CCC_BLOCK_READ (1<<2) +#define CCC_STREAM_WRITE (1<<3) +#define CCC_BLOCK_WRITE (1<<4) +#define CCC_ERASE (1<<5) +#define CCC_WRITE_PROT (1<<6) +#define CCC_LOCK_CARD (1<<7) +#define CCC_APP_SPEC (1<<8) +#define CCC_IO_MODE (1<<9) +#define CCC_SWITCH (1<<10) + +#define MMC_ERASE_ARG 0x00000000 +#define MMC_SECURE_ERASE_ARG 0x80000000 +#define MMC_TRIM_ARG 0x00000001 +#define MMC_DISCARD_ARG 0x00000003 + #define SECURE_ERASE 0x80000000
#define MMC_STATUS_MASK (~0x0206BF7F) @@ -160,8 +194,12 @@ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ +#define EXT_CSD_REL_WR_SEC_C 222 /* RO */ +#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ #define EXT_CSD_BOOT_MULT 226 /* RO */ +#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ +#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
/* * EXT_CSD field definitions @@ -178,6 +216,12 @@ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+/* EXT_CSD[231] */ +#define EXT_CSD_SEC_ER_EN (1<<0) +#define EXT_CSD_SEC_BD_BLK_EN (1<<2) +#define EXT_CSD_SEC_GB_CL_EN (1<<4) +#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 later */ + #define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) #define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0) @@ -187,7 +231,6 @@ #define EXT_CSD_BOOT_PART_NUM(x) (x << 3) #define EXT_CSD_PARTITION_ACCESS(x) (x << 0)
- #define R1_ILLEGAL_COMMAND (1 << 22) #define R1_APP_CMD (1 << 5)
@@ -268,10 +311,15 @@ struct mmc { ushort rca; char part_config; char part_num; + ushort cmdclass; uint tran_speed; uint read_bl_len; uint write_bl_len; uint erase_grp_size; + uint erase_timeout_mult; + char sec_feature_support; + uint sec_erase_mult; + uint sec_erase_timeout; u64 capacity; u64 capacity_user; u64 capacity_boot;

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 giving some incorrect information.
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.zhang@freescale.com --- changes for V4: - update the commit message - mask the cmdclass to 12 bit only
drivers/mmc/mmc.c | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index e1461a9..cf6de83 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) & 0xfff; + /* 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. @@ -971,18 +1007,6 @@ static int mmc_startup(struct mmc *mmc)
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); }
/* store the partition info of emmc */

This patch enhances the currently implemented erase procedure in u-boot, Not all cards support secure erase feature. We should make a difference between them. For eMMC card that support erase group feature, check the the command class first, then try to align the erase group size before we actually sending the command.
Erase sequence after this patch: 1. check if erase command is supported by the card. If not just return. 2. Check the erase range to see if it is group aligned. For mmc card the minimum erase size should be one erase group. For SD card it is fixed to one block(512), 3. If not, aligned the erase rang according to the erase group size. 4. Send erase command to erase card once one erase group. 5. If it's a SD card, erase with arg 0x00000000 should be send. else if secure feature is supported, erase with arg 0x80000000 (Spec eMMC 4.41). else erase with arg 0x00000000.(Trim and discard are ignored here) 6. Check card status after erase operation is completed.
Signed-off-by: Haijun Zhang haijun.zhang@freescale.com --- changes for V4: - Update the commit message changes for V3: - update the commit message and secure feature supporting judgment.
drivers/mmc/mmc_write.c | 68 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 10 deletions(-)
diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index aa2fdef..c2dafa3 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -17,6 +17,10 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) struct mmc_cmd cmd; ulong end; int err, start_cmd, end_cmd; + uint arg = 0; + + if (!(mmc->cmdclass & CCC_ERASE)) + return NOT_SUPPORT;
if (mmc->high_capacity) { end = start + blkcnt - 1; @@ -48,8 +52,15 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) if (err) goto err_out;
+ /* SD card only support %MMC_ERASE_ARG */ + if (!IS_SD(mmc) && + (mmc->sec_feature_support & EXT_CSD_SEC_ER_EN)) + arg = MMC_SECURE_ERASE_ARG; + else + arg = MMC_ERASE_ARG; + cmd.cmdidx = MMC_CMD_ERASE; - cmd.cmdarg = SECURE_ERASE; + cmd.cmdarg = arg; cmd.resp_type = MMC_RSP_R1b;
err = mmc_send_cmd(mmc, &cmd, NULL); @@ -69,24 +80,61 @@ unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt) struct mmc *mmc = find_mmc_device(dev_num); lbaint_t blk = 0, blk_r = 0; int timeout = 1000; + int res; + bool align = true;
if (!mmc) return -1;
+ if (!(mmc->cmdclass & CCC_ERASE)) { + printf("\nErase operation is not support by card\n"); + return NOT_SUPPORT; + } + if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size)) + align = false; + + res = start % mmc->erase_grp_size; + if (res) { + res = mmc->erase_grp_size - res; + start += res; + if (blkcnt > res) + blkcnt -= res; + else { + printf("\nErase size smaller than Erase group " + "size [0x%x] is not support by the device.\n", + mmc->erase_grp_size); + return NOT_SUPPORT; + } + } + + res = blkcnt % mmc->erase_grp_size; + if (res) + blkcnt -= res; + + if (!blkcnt) { + printf("\nErase size smaller than Erase group size [0x%x] " + "is not support by the device.\n", + mmc->erase_grp_size); + return NOT_SUPPORT; + } + + if (!align) 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); + "The erase range would be change to " + "0x" LBAF "~0x" LBAF "\n\n", + mmc->erase_grp_size, start, start + blkcnt); +
while (blk < blkcnt) { - blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? - mmc->erase_grp_size : (blkcnt - blk); + if ((blkcnt - blk) >= mmc->erase_grp_size) + blk_r = mmc->erase_grp_size; err = mmc_erase_t(mmc, start + blk, blk_r); - if (err) - break; + if (err) { + printf("\nErase range from 0x" LBAF "~0x" LBAF + " Failed\n", start + blk, blkcnt); + return COMM_ERR; + }
blk += blk_r;

If the block range was not aligned, we try to align the range size, The block range actually erased should be less or equal to the block range sent. If error occured during erase procedure witch part of them being erased, users should resend the block rang to continue erase the rest of them.
Error return, zero return, has failed.
Signed-off-by: Haijun Zhang haijun.zhang@freescale.com --- changes for V4: - update commit message changes for V3: - no changes
common/cmd_mmc.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 67a94a7..d4225f6 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -397,6 +397,13 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) BUG(); }
+ if (state == MMC_ERASE) { + printf("%d blocks %s: %s\n", + (n <= cnt) && (n > 0) ? n : 0, argv[1], + (n <= cnt) && (n > 0) ? "OK" : "ERROR"); + return (n <= cnt) && (n > 0) ? 0 : 1; + } + printf("%d blocks %s: %s\n", n, argv[1], (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? 0 : 1;

Once mmc initialization was failed has_init should be cleared to 0, prepare for the next initialization.
Once mmcinfo command failed, error should be reported instead of printing incorrect mmc device information.
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 => 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.zhang@freescale.com --- changes for V4: - no changes
common/cmd_mmc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index d4225f6..5af1e92 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -115,7 +115,8 @@ static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) mmc = find_mmc_device(curr_device);
if (mmc) { - mmc_init(mmc); + if (mmc_init(mmc)) + return 1;
print_mmcinfo(mmc); return 0; @@ -191,9 +192,10 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
mmc->has_init = 0;
- if (mmc_init(mmc)) + if (mmc_init(mmc)) { + mmc->has_init = 0; return 1; - else + } else return 0; } else if (strncmp(argv[1], "part", 4) == 0) { block_dev_desc_t *mmc_dev;

From: Haijun Zhang Haijun.Zhang@freescale.com
Esdhc host version number is incorrect in host capacity register. The value read from was 0x14. Correct it to 0x13.
Signed-off-by: Haijun Zhang haijun.zhang@freescale.com --- changes for V4: - no changes
arch/powerpc/include/asm/config_mpc85xx.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 99e16bd..15affdc 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -591,6 +591,7 @@ #define CONFIG_SYS_NUM_FM2_DTSEC 8 #define CONFIG_SYS_NUM_FM2_10GEC 2 #define CONFIG_NUM_DDR_CONTROLLERS 3 +#define CONFIG_FSL_SDHC_V2_3 #else #define CONFIG_MAX_CPUS 8 #define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1 }

The max timeout value esdhc host can accept is about 2.69 sec. At 50 Mhz SD_CLK period, the max busy timeout value = 2^27 * SD_CLK period ~= 2.69 sec.
In case erase command CMD38 timeout is caculated by mult * 300ms * num(unit by erase group), so the time one erase group need should be more than 300ms, 5000ms should be enough.
1. Add data reset procedure for data error and command with busy error. 2. Add timeout value detecting during waiting for transfer complete. 3. Ignore Command inhibit (DAT) state when excuting CMD12. 4. Add command CRC error detecting. 5. Enlarged the timeout value used for busy state release.
Signed-off-by: Haijun Zhang Haijun.Zhang@freescale.com --- changes for V4: - no changes changes for V3: - changed the '-1' to '0xffffffffU' - redundant check command and data error after while loop.
drivers/mmc/fsl_esdhc.c | 164 +++++++++++++++++++++++++++++++----------------- 1 file changed, 106 insertions(+), 58 deletions(-)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 9f4d3a2..134a02d 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -266,26 +266,36 @@ static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { uint xfertyp; - uint irqstat; + uint irqstat = 0, mask; struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; + int ret = 0, timeout; + + esdhc_write32(®s->irqstat, 0xffffffffU); + + sync(); + + mask = PRSSTAT_CICHB | PRSSTAT_CIDHB;
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) return 0; +#else + if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + mask &= ~PRSSTAT_CIDHB; #endif
- esdhc_write32(®s->irqstat, -1); - - sync(); - /* Wait for the bus to be idle */ - while ((esdhc_read32(®s->prsstat) & PRSSTAT_CICHB) || - (esdhc_read32(®s->prsstat) & PRSSTAT_CIDHB)) - ; - - while (esdhc_read32(®s->prsstat) & PRSSTAT_DLA) - ; + timeout = 1000; + while (esdhc_read32(®s->prsstat) & mask) { + if (timeout == 0) { + printf("\nController never released inhibit bit(s).\n"); + ret = COMM_ERR; + goto reset; + } + timeout--; + mdelay(1); + }
/* Wait at least 8 SD clock cycles before the next command */ /* @@ -296,11 +306,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
/* Set up for a data transfer if we have one */ if (data) { - int err; - - err = esdhc_setup_data(mmc, data); - if(err) - return err; + ret = esdhc_setup_data(mmc, data); + if (ret) + goto reset; }
/* Figure out the transfer arguments */ @@ -325,43 +333,14 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
irqstat = esdhc_read32(®s->irqstat);
- /* Reset CMD and DATA portions on error */ - if (irqstat & CMD_ERR) { - esdhc_write32(®s->sysctl, esdhc_read32(®s->sysctl) | - SYSCTL_RSTC); - while (esdhc_read32(®s->sysctl) & SYSCTL_RSTC) - ; - - if (data) { - esdhc_write32(®s->sysctl, - esdhc_read32(®s->sysctl) | - SYSCTL_RSTD); - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD)) - ; - } + if (irqstat & IRQSTAT_CTOE) { + ret = TIMEOUT; + goto reset; }
- if (irqstat & IRQSTAT_CTOE) - return TIMEOUT; - - if (irqstat & CMD_ERR) - return COMM_ERR; - - /* Workaround for ESDHC errata ENGcm03648 */ - if (!data && (cmd->resp_type & MMC_RSP_BUSY)) { - int timeout = 2500; - - /* Poll on DATA0 line for cmd with busy signal for 250 ms */ - while (timeout > 0 && !(esdhc_read32(®s->prsstat) & - PRSSTAT_DAT0)) { - udelay(100); - timeout--; - } - - if (timeout <= 0) { - printf("Timeout waiting for DAT0 to go high!\n"); - return TIMEOUT; - } + if (irqstat & CMD_ERR) { + ret = COMM_ERR; + goto reset; }
/* Copy the response to the response buffer */ @@ -379,7 +358,20 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) } else cmd->response[0] = esdhc_read32(®s->cmdrsp0);
- /* Wait until all of the blocks are transferred */ + /* + * At 50 Mhz SD_CLK period, the max busy timeout + * value or data transfer time need was about + * = 2^27 * SD_CLK period ~= 2.69 sec. + * So wait max 10 sec for data transfer complete or busy + * state release. + */ + timeout = 10000; + + /* + * eSDHC host V2.3 has response busy interrupt, so + * we should wait for busy state to be released and data + * was out of programing state before next command send. + */ if (data) { #ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO esdhc_pio_read_write(mmc, data); @@ -387,20 +379,76 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) do { irqstat = esdhc_read32(®s->irqstat);
- if (irqstat & IRQSTAT_DTOE) - return TIMEOUT; + if (irqstat & IRQSTAT_DTOE) { + ret = TIMEOUT; + break; + }
- if (irqstat & DATA_ERR) - return COMM_ERR; - } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE); + if (irqstat & DATA_ERR) { + ret = COMM_ERR; + break; + } + + if (timeout <= 0) { + ret = TIMEOUT; + break; + } + mdelay(1); + timeout--; + } while (((irqstat & DATA_COMPLETE) != DATA_COMPLETE) && + (esdhc_read32(®s->prsstat) & PRSSTAT_DLA)); #endif if (data->flags & MMC_DATA_READ) check_and_invalidate_dcache_range(cmd, data); }
- esdhc_write32(®s->irqstat, -1); + /* Workaround for ESDHC errata ENGcm03648 */ + if (!data && (cmd->resp_type & MMC_RSP_BUSY)) { + int timeout = 5000; + + /* Poll on DATA0 line for cmd with busy signal for 5 sec */ + while (timeout > 0 && !(esdhc_read32(®s->prsstat) & + PRSSTAT_DAT0)) { + mdelay(1); + timeout--; + } + + if (timeout <= 0) { + printf("\nTimeout waiting for DAT0 to go high!\n"); + ret = TIMEOUT; + goto reset; + } + } + + if (esdhc_read32(®s->irqstat) & (DATA_ERR | CMD_ERR)) + ret = COMM_ERR; + + if (ret) + goto reset; + + esdhc_write32(®s->irqstat, 0xffffffffU);
return 0; + +reset: + + /* Reset CMD and DATA portions on error */ + esdhc_write32(®s->sysctl, esdhc_read32(®s->sysctl) | + SYSCTL_RSTC); + while (esdhc_read32(®s->sysctl) & SYSCTL_RSTC) + ; + + if (data || (cmd->resp_type & MMC_RSP_BUSY)) { + esdhc_write32(®s->sysctl, + esdhc_read32(®s->sysctl) | + SYSCTL_RSTD); + while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD)) + ; + } + + esdhc_write32(®s->irqstat, 0xffffffffU); + + return ret; }
static void set_sysctl(struct mmc *mmc, uint clock)

Hi, Pantelis
These are the newest version of this patch set. Expect your advice.
Regards & Thanks.
-- Haijun
-----Original Message----- From: Haijun Zhang [mailto:haijun.zhang@freescale.com] Sent: Tuesday, December 10, 2013 4:21 PM To: panto@antoniou-consulting.com Cc: u-boot@lists.denx.de; Xie Xiaobo-R63061; Sun York-R58495; trini@ti.com; sbabic@denx.de; rjbarnet@rockwellcollins.com; jh80.chung@samsung.com; michael@amarulasolutions.com; Zhang Haijun-B42677; Zhang Haijun-B42677 Subject: [PATCH 1/7 V4] mmc: Add some usefull macro definition
From: Haijun Zhang Haijun.Zhang@freescale.com
Add command class define. Add mmc erase and secure erase define. Add secure erase and trim support bit define.
Signed-off-by: Haijun Zhang haijun.zhang@freescale.com
changes for V4: - no changes changes for V3: - No changes
include/mmc.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/mmc.h b/include/mmc.h index cb558da..08f0f3e 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -53,6 +53,7 @@ #define COMM_ERR -18 /* Communications Error */ #define TIMEOUT -19 #define IN_PROGRESS -20 /* operation is in progress */ +#define NOT_SUPPORT -21 /* Operation is not support */
#define MMC_CMD_GO_IDLE_STATE 0 #define MMC_CMD_SEND_OP_COND 1 @@ -105,6 +106,39 @@ #define OCR_VOLTAGE_MASK 0x007FFF80 #define OCR_ACCESS_MODE 0x60000000
+/*
- Card Command Classes (CCC)
- (0) Basic protocol functions (CMD0,1,2,3,4,7,9,10,12,13,15)
- (and for SPI, CMD58,59)
- (1) Stream read commands (CMD11)
- (2) Block read commands (CMD16,17,18)
- (3) Stream write commands (CMD20)
- (4) Block write commands (CMD16,24,25,26,27)
- (5) Ability to erase blocks (CMD32,33,34,35,36,37,38,39)
- (6) Able to write protect blocks (CMD28,29,30)
- (7) Able to lock down card (CMD16,CMD42)
- (8) Application specific (CMD55,56,57,ACMD*)
- (9) I/O mode (CMD5,39,40,52,53)
- (10) High speed switch (CMD6,34,35,36,37,50) */
+#define CCC_BASIC (1<<0) +#define CCC_STREAM_READ (1<<1) +#define CCC_BLOCK_READ (1<<2) +#define CCC_STREAM_WRITE (1<<3) +#define CCC_BLOCK_WRITE (1<<4) +#define CCC_ERASE (1<<5) +#define CCC_WRITE_PROT (1<<6) +#define CCC_LOCK_CARD (1<<7) +#define CCC_APP_SPEC (1<<8) +#define CCC_IO_MODE (1<<9) +#define CCC_SWITCH (1<<10)
+#define MMC_ERASE_ARG 0x00000000 +#define MMC_SECURE_ERASE_ARG 0x80000000 +#define MMC_TRIM_ARG 0x00000001 +#define MMC_DISCARD_ARG 0x00000003
#define SECURE_ERASE 0x80000000
#define MMC_STATUS_MASK (~0x0206BF7F) @@ -160,8 +194,12 @@ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ +#define EXT_CSD_REL_WR_SEC_C 222 /* RO */ +#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ #define EXT_CSD_BOOT_MULT 226 /* RO */ +#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ +#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
/*
- EXT_CSD field definitions
@@ -178,6 +216,12 @@ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+/* EXT_CSD[231] */ +#define EXT_CSD_SEC_ER_EN (1<<0) +#define EXT_CSD_SEC_BD_BLK_EN (1<<2) +#define EXT_CSD_SEC_GB_CL_EN (1<<4) +#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 later */
#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) #define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0) @@ -187,7 +231,6 @@ #define EXT_CSD_BOOT_PART_NUM(x) (x << 3) #define EXT_CSD_PARTITION_ACCESS(x) (x << 0)
#define R1_ILLEGAL_COMMAND (1 << 22) #define R1_APP_CMD (1 << 5)
@@ -268,10 +311,15 @@ struct mmc { ushort rca; char part_config; char part_num;
- ushort cmdclass; uint tran_speed; uint read_bl_len; uint write_bl_len; uint erase_grp_size;
- uint erase_timeout_mult;
- char sec_feature_support;
- uint sec_erase_mult;
- uint sec_erase_timeout; u64 capacity; u64 capacity_user; u64 capacity_boot;
-- 1.8.4.1

Hi, Haijun.
On 12/10/2013 05:20 PM, Haijun Zhang wrote:
From: Haijun Zhang Haijun.Zhang@freescale.com
Add command class define. Add mmc erase and secure erase define. Add secure erase and trim support bit define.
Signed-off-by: Haijun Zhang haijun.zhang@freescale.com
changes for V4: - no changes changes for V3: - No changes
include/mmc.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/mmc.h b/include/mmc.h index cb558da..08f0f3e 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -53,6 +53,7 @@ #define COMM_ERR -18 /* Communications Error */ #define TIMEOUT -19 #define IN_PROGRESS -20 /* operation is in progress */ +#define NOT_SUPPORT -21 /* Operation is not support */
#define MMC_CMD_GO_IDLE_STATE 0 #define MMC_CMD_SEND_OP_COND 1 @@ -105,6 +106,39 @@ #define OCR_VOLTAGE_MASK 0x007FFF80 #define OCR_ACCESS_MODE 0x60000000
+/*
- Card Command Classes (CCC)
- (0) Basic protocol functions (CMD0,1,2,3,4,7,9,10,12,13,15)
- (and for SPI, CMD58,59)
- (1) Stream read commands (CMD11)
- (2) Block read commands (CMD16,17,18)
- (3) Stream write commands (CMD20)
- (4) Block write commands (CMD16,24,25,26,27)
- (5) Ability to erase blocks (CMD32,33,34,35,36,37,38,39)
- (6) Able to write protect blocks (CMD28,29,30)
- (7) Able to lock down card (CMD16,CMD42)
- (8) Application specific (CMD55,56,57,ACMD*)
- (9) I/O mode (CMD5,39,40,52,53)
- (10) High speed switch (CMD6,34,35,36,37,50)
- */
+#define CCC_BASIC (1<<0) +#define CCC_STREAM_READ (1<<1) +#define CCC_BLOCK_READ (1<<2) +#define CCC_STREAM_WRITE (1<<3) +#define CCC_BLOCK_WRITE (1<<4) +#define CCC_ERASE (1<<5) +#define CCC_WRITE_PROT (1<<6) +#define CCC_LOCK_CARD (1<<7) +#define CCC_APP_SPEC (1<<8) +#define CCC_IO_MODE (1<<9) +#define CCC_SWITCH (1<<10)
+#define MMC_ERASE_ARG 0x00000000 +#define MMC_SECURE_ERASE_ARG 0x80000000 +#define MMC_TRIM_ARG 0x00000001 +#define MMC_DISCARD_ARG 0x00000003
#define SECURE_ERASE 0x80000000
#define MMC_STATUS_MASK (~0x0206BF7F) @@ -160,8 +194,12 @@ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ +#define EXT_CSD_REL_WR_SEC_C 222 /* RO */ +#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ #define EXT_CSD_BOOT_MULT 226 /* RO */ +#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ +#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
/*
- EXT_CSD field definitions
@@ -178,6 +216,12 @@ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+/* EXT_CSD[231] */
If you want to add the comment for EXT_CSD[231], I think good like this. /* SEC_FEATURE_SUPPORT[231] Field definitions */
Best Regards, Jaehoon Chung
+#define EXT_CSD_SEC_ER_EN (1<<0) +#define EXT_CSD_SEC_BD_BLK_EN (1<<2) +#define EXT_CSD_SEC_GB_CL_EN (1<<4) +#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 later */
#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) #define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0) @@ -187,7 +231,6 @@ #define EXT_CSD_BOOT_PART_NUM(x) (x << 3) #define EXT_CSD_PARTITION_ACCESS(x) (x << 0)
#define R1_ILLEGAL_COMMAND (1 << 22) #define R1_APP_CMD (1 << 5)
@@ -268,10 +311,15 @@ struct mmc { ushort rca; char part_config; char part_num;
- ushort cmdclass; uint tran_speed; uint read_bl_len; uint write_bl_len; uint erase_grp_size;
- uint erase_timeout_mult;
- char sec_feature_support;
- uint sec_erase_mult;
- uint sec_erase_timeout; u64 capacity; u64 capacity_user; u64 capacity_boot;

On 12/27/2013 07:29 PM, Jaehoon Chung wrote:
Hi, Haijun.
On 12/10/2013 05:20 PM, Haijun Zhang wrote:
From: Haijun Zhang Haijun.Zhang@freescale.com
Add command class define. Add mmc erase and secure erase define. Add secure erase and trim support bit define.
Signed-off-by: Haijun Zhang haijun.zhang@freescale.com
changes for V4: - no changes changes for V3: - No changes
include/mmc.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/mmc.h b/include/mmc.h index cb558da..08f0f3e 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -53,6 +53,7 @@ #define COMM_ERR -18 /* Communications Error */ #define TIMEOUT -19 #define IN_PROGRESS -20 /* operation is in progress */ +#define NOT_SUPPORT -21 /* Operation is not support */
#define MMC_CMD_GO_IDLE_STATE 0 #define MMC_CMD_SEND_OP_COND 1 @@ -105,6 +106,39 @@ #define OCR_VOLTAGE_MASK 0x007FFF80 #define OCR_ACCESS_MODE 0x60000000
+/*
- Card Command Classes (CCC)
- (0) Basic protocol functions (CMD0,1,2,3,4,7,9,10,12,13,15)
- (and for SPI, CMD58,59)
- (1) Stream read commands (CMD11)
- (2) Block read commands (CMD16,17,18)
- (3) Stream write commands (CMD20)
- (4) Block write commands (CMD16,24,25,26,27)
- (5) Ability to erase blocks (CMD32,33,34,35,36,37,38,39)
- (6) Able to write protect blocks (CMD28,29,30)
- (7) Able to lock down card (CMD16,CMD42)
- (8) Application specific (CMD55,56,57,ACMD*)
- (9) I/O mode (CMD5,39,40,52,53)
- (10) High speed switch (CMD6,34,35,36,37,50)
- */
+#define CCC_BASIC (1<<0) +#define CCC_STREAM_READ (1<<1) +#define CCC_BLOCK_READ (1<<2) +#define CCC_STREAM_WRITE (1<<3) +#define CCC_BLOCK_WRITE (1<<4) +#define CCC_ERASE (1<<5) +#define CCC_WRITE_PROT (1<<6) +#define CCC_LOCK_CARD (1<<7) +#define CCC_APP_SPEC (1<<8) +#define CCC_IO_MODE (1<<9) +#define CCC_SWITCH (1<<10)
+#define MMC_ERASE_ARG 0x00000000 +#define MMC_SECURE_ERASE_ARG 0x80000000 +#define MMC_TRIM_ARG 0x00000001 +#define MMC_DISCARD_ARG 0x00000003
#define SECURE_ERASE 0x80000000
#define MMC_STATUS_MASK (~0x0206BF7F)
@@ -160,8 +194,12 @@ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ +#define EXT_CSD_REL_WR_SEC_C 222 /* RO */ +#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ #define EXT_CSD_BOOT_MULT 226 /* RO */ +#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ +#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
/*
- EXT_CSD field definitions
@@ -178,6 +216,12 @@ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+/* EXT_CSD[231] */
If you want to add the comment for EXT_CSD[231], I think good like this. /* SEC_FEATURE_SUPPORT[231] Field definitions */
Best Regards, Jaehoon Chung
Thanks.
I'll add this.
-- Haijun
+#define EXT_CSD_SEC_ER_EN (1<<0) +#define EXT_CSD_SEC_BD_BLK_EN (1<<2) +#define EXT_CSD_SEC_GB_CL_EN (1<<4) +#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 later */
- #define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) #define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0)
@@ -187,7 +231,6 @@ #define EXT_CSD_BOOT_PART_NUM(x) (x << 3) #define EXT_CSD_PARTITION_ACCESS(x) (x << 0)
- #define R1_ILLEGAL_COMMAND (1 << 22) #define R1_APP_CMD (1 << 5)
@@ -268,10 +311,15 @@ struct mmc { ushort rca; char part_config; char part_num;
- ushort cmdclass; uint tran_speed; uint read_bl_len; uint write_bl_len; uint erase_grp_size;
- uint erase_timeout_mult;
- char sec_feature_support;
- uint sec_erase_mult;
- uint sec_erase_timeout; u64 capacity; u64 capacity_user; u64 capacity_boot;

Hi, Panto
This patch set are superseded. There are revision five.
Best Regards, -- Haijun
On 12/10/2013 04:20 PM, Haijun Zhang wrote:
From: Haijun Zhang Haijun.Zhang@freescale.com
Add command class define. Add mmc erase and secure erase define. Add secure erase and trim support bit define.
Signed-off-by: Haijun Zhang haijun.zhang@freescale.com
changes for V4: - no changes changes for V3: - No changes
include/mmc.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/mmc.h b/include/mmc.h index cb558da..08f0f3e 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -53,6 +53,7 @@ #define COMM_ERR -18 /* Communications Error */ #define TIMEOUT -19 #define IN_PROGRESS -20 /* operation is in progress */ +#define NOT_SUPPORT -21 /* Operation is not support */
#define MMC_CMD_GO_IDLE_STATE 0 #define MMC_CMD_SEND_OP_COND 1 @@ -105,6 +106,39 @@ #define OCR_VOLTAGE_MASK 0x007FFF80 #define OCR_ACCESS_MODE 0x60000000
+/*
- Card Command Classes (CCC)
- (0) Basic protocol functions (CMD0,1,2,3,4,7,9,10,12,13,15)
- (and for SPI, CMD58,59)
- (1) Stream read commands (CMD11)
- (2) Block read commands (CMD16,17,18)
- (3) Stream write commands (CMD20)
- (4) Block write commands (CMD16,24,25,26,27)
- (5) Ability to erase blocks (CMD32,33,34,35,36,37,38,39)
- (6) Able to write protect blocks (CMD28,29,30)
- (7) Able to lock down card (CMD16,CMD42)
- (8) Application specific (CMD55,56,57,ACMD*)
- (9) I/O mode (CMD5,39,40,52,53)
- (10) High speed switch (CMD6,34,35,36,37,50)
- */
+#define CCC_BASIC (1<<0) +#define CCC_STREAM_READ (1<<1) +#define CCC_BLOCK_READ (1<<2) +#define CCC_STREAM_WRITE (1<<3) +#define CCC_BLOCK_WRITE (1<<4) +#define CCC_ERASE (1<<5) +#define CCC_WRITE_PROT (1<<6) +#define CCC_LOCK_CARD (1<<7) +#define CCC_APP_SPEC (1<<8) +#define CCC_IO_MODE (1<<9) +#define CCC_SWITCH (1<<10)
+#define MMC_ERASE_ARG 0x00000000 +#define MMC_SECURE_ERASE_ARG 0x80000000 +#define MMC_TRIM_ARG 0x00000001 +#define MMC_DISCARD_ARG 0x00000003
#define SECURE_ERASE 0x80000000
#define MMC_STATUS_MASK (~0x0206BF7F)
@@ -160,8 +194,12 @@ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ +#define EXT_CSD_REL_WR_SEC_C 222 /* RO */ +#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ #define EXT_CSD_BOOT_MULT 226 /* RO */ +#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ +#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
/*
- EXT_CSD field definitions
@@ -178,6 +216,12 @@ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+/* EXT_CSD[231] */ +#define EXT_CSD_SEC_ER_EN (1<<0) +#define EXT_CSD_SEC_BD_BLK_EN (1<<2) +#define EXT_CSD_SEC_GB_CL_EN (1<<4) +#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 later */
- #define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) #define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0)
@@ -187,7 +231,6 @@ #define EXT_CSD_BOOT_PART_NUM(x) (x << 3) #define EXT_CSD_PARTITION_ACCESS(x) (x << 0)
- #define R1_ILLEGAL_COMMAND (1 << 22) #define R1_APP_CMD (1 << 5)
@@ -268,10 +311,15 @@ struct mmc { ushort rca; char part_config; char part_num;
- ushort cmdclass; uint tran_speed; uint read_bl_len; uint write_bl_len; uint erase_grp_size;
- uint erase_timeout_mult;
- char sec_feature_support;
- uint sec_erase_mult;
- uint sec_erase_timeout; u64 capacity; u64 capacity_user; u64 capacity_boot;
participants (4)
-
Haijun Zhang
-
Haijun.Zhang@freescale.com
-
Jaehoon Chung
-
Zhang Haijun