From: Peng Fan <van.freenix@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH V4 1/2] mmc: sd: extracting erase related information from sd status
Date: Thu, 1 Sep 2016 11:13:38 +0800 [thread overview]
Message-ID: <1472699619-4368-1-git-send-email-peng.fan@nxp.com> (raw)
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.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Stefan Wahren <stefan.wahren@i2se.com>
Cc: Clemens Gruber <clemens.gruber@pqgruber.com>
Cc: Kever Yang <kever.yang@rock-chips.com>
Cc: Eric Nelson <eric@nelint.com>
Cc: Stephen Warren <swarren@nvidia.com>
---
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 <div64.h>
#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 <linux/list.h>
+#include <linux/sizes.h>
#include <linux/compiler.h>
#include <part.h>
@@ -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;
--
2.6.2
next reply other threads:[~2016-09-01 3:13 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20160901031407epcas1p3e0ab48ce0e709a80b65cac28eccdf155@epcas1p3.samsung.com>
2016-09-01 3:13 ` Peng Fan [this message]
2016-09-01 3:13 ` [U-Boot] [PATCH V4 2/2] mmc: sd: optimize erase Peng Fan
2016-09-07 6:52 ` [U-Boot] [PATCH V4 1/2] mmc: sd: extracting erase related information from sd status Jaehoon Chung
2016-09-08 1:42 ` Peng Fan
2016-09-08 1:49 ` Jaehoon Chung
2016-09-08 1:51 ` Peng Fan
2016-09-08 13:47 ` Jaehoon Chung
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1472699619-4368-1-git-send-email-peng.fan@nxp.com \
--to=van.freenix@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.