From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peng Fan Date: Thu, 8 Sep 2016 09:42:56 +0800 Subject: [U-Boot] [PATCH V4 1/2] mmc: sd: extracting erase related information from sd status In-Reply-To: References: <1472699619-4368-1-git-send-email-peng.fan@nxp.com> Message-ID: <20160908014254.GB9097@linux-7smt.suse> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Jaehoon, On Wed, Sep 07, 2016 at 03:52:53PM +0900, Jaehoon Chung wrote: >Hi Peng, > >On 09/01/2016 12:13 PM, Peng Fan wrote: >> Add function to read SD_STATUS information. >> According to the information, get erase_timeout/erase_size/erase_offset. >> Add a structure sd_ssr to include the erase related information. > >Sorry for late..I'm testing with your patch on my SD-card. >After that, I will apply yours. Before applied this, i will check more carefully for not doing previous my mistake. The issue in the previous patch set is that linux/size.h is not included in sandbox.h. In this patchset, I include linux/size.h in mmc.h:) Thanks, Peng. > >Best Regards, >Jaehoon Chung > >> >> Signed-off-by: Peng Fan >> Cc: Jaehoon Chung >> Cc: Simon Glass >> Cc: Bin Meng >> Cc: Stefan Wahren >> Cc: Clemens Gruber >> Cc: Kever Yang >> Cc: Eric Nelson >> Cc: Stephen Warren >> --- >> >> V4: >> include linux/sizes.h in mmc.h to avoid build break. >> >> I dropped patch [2,3,4]/5 in V2, which is not a must in this optimization case. >> >> V3: >> No change. >> >> V2: >> Address Jaehoon's comments for V1 >> drivers/mmc/mmc.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> include/mmc.h | 9 ++++++++ >> 2 files changed, 77 insertions(+) >> >> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c >> index 43ea0bb..0312da9 100644 >> --- a/drivers/mmc/mmc.c >> +++ b/drivers/mmc/mmc.c >> @@ -21,6 +21,14 @@ >> #include >> #include "mmc_private.h" >> >> +static const unsigned int sd_au_size[] = { >> + 0, SZ_16K / 512, SZ_32K / 512, >> + SZ_64K / 512, SZ_128K / 512, SZ_256K / 512, >> + SZ_512K / 512, SZ_1M / 512, SZ_2M / 512, >> + SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512, >> + SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512, SZ_64M / 512, >> +}; >> + >> #ifndef CONFIG_DM_MMC_OPS >> __weak int board_mmc_getwp(struct mmc *mmc) >> { >> @@ -945,6 +953,62 @@ retry_scr: >> return 0; >> } >> >> +static int sd_read_ssr(struct mmc *mmc) >> +{ >> + int err, i; >> + struct mmc_cmd cmd; >> + ALLOC_CACHE_ALIGN_BUFFER(uint, ssr, 16); >> + struct mmc_data data; >> + int timeout = 3; >> + unsigned int au, eo, et, es; >> + >> + cmd.cmdidx = MMC_CMD_APP_CMD; >> + cmd.resp_type = MMC_RSP_R1; >> + cmd.cmdarg = mmc->rca << 16; >> + >> + err = mmc_send_cmd(mmc, &cmd, NULL); >> + if (err) >> + return err; >> + >> + cmd.cmdidx = SD_CMD_APP_SD_STATUS; >> + cmd.resp_type = MMC_RSP_R1; >> + cmd.cmdarg = 0; >> + >> +retry_ssr: >> + data.dest = (char *)ssr; >> + data.blocksize = 64; >> + data.blocks = 1; >> + data.flags = MMC_DATA_READ; >> + >> + err = mmc_send_cmd(mmc, &cmd, &data); >> + if (err) { >> + if (timeout--) >> + goto retry_ssr; >> + >> + return err; >> + } >> + >> + for (i = 0; i < 16; i++) >> + ssr[i] = be32_to_cpu(ssr[i]); >> + >> + au = (ssr[2] >> 12) & 0xF; >> + if ((au <= 9) || (mmc->version == SD_VERSION_3)) { >> + mmc->ssr.au = sd_au_size[au]; >> + es = (ssr[3] >> 24) & 0xFF; >> + es |= (ssr[2] & 0xFF) << 8; >> + et = (ssr[3] >> 18) & 0x3F; >> + if (es && et) { >> + eo = (ssr[3] >> 16) & 0x3; >> + mmc->ssr.erase_timeout = (et * 1000) / es; >> + mmc->ssr.erase_offset = eo * 1000; >> + } >> + } else { >> + debug("Invalid Allocation Unit Size.\n"); >> + } >> + >> + return 0; >> +} >> + >> /* frequency bases */ >> /* divided by 10 to be nice to platforms without floating point */ >> static const int fbase[] = { >> @@ -1350,6 +1414,10 @@ static int mmc_startup(struct mmc *mmc) >> mmc_set_bus_width(mmc, 4); >> } >> >> + err = sd_read_ssr(mmc); >> + if (err) >> + return err; >> + >> if (mmc->card_caps & MMC_MODE_HS) >> mmc->tran_speed = 50000000; >> else >> diff --git a/include/mmc.h b/include/mmc.h >> index aa6d5d1..e815eb3 100644 >> --- a/include/mmc.h >> +++ b/include/mmc.h >> @@ -11,6 +11,7 @@ >> #define _MMC_H_ >> >> #include >> +#include >> #include >> #include >> >> @@ -102,6 +103,7 @@ >> #define SD_CMD_SWITCH_UHS18V 11 >> >> #define SD_CMD_APP_SET_BUS_WIDTH 6 >> +#define SD_CMD_APP_SD_STATUS 13 >> #define SD_CMD_ERASE_WR_BLK_START 32 >> #define SD_CMD_ERASE_WR_BLK_END 33 >> #define SD_CMD_APP_SEND_OP_COND 41 >> @@ -392,6 +394,12 @@ struct mmc_config { >> unsigned char part_type; >> }; >> >> +struct sd_ssr { >> + unsigned int au; /* In sectors */ >> + unsigned int erase_timeout; /* In milliseconds */ >> + unsigned int erase_offset; /* In milliseconds */ >> +}; >> + >> /* >> * With CONFIG_DM_MMC enabled, struct mmc can be accessed from the MMC device >> * with mmc_get_mmc_dev(). >> @@ -426,6 +434,7 @@ struct mmc { >> uint write_bl_len; >> uint erase_grp_size; /* in 512-byte sectors */ >> uint hc_wp_grp_size; /* in 512-byte sectors */ >> + struct sd_ssr ssr; /* SD status register */ >> u64 capacity; >> u64 capacity_user; >> u64 capacity_boot; >> >