From: Shawn Lin <shawn.lin@rock-chips.com>
To: Adrian Hunter <adrian.hunter@intel.com>,
Ulf Hansson <ulf.hansson@linaro.org>
Cc: Michal Simek <michal.simek@xilinx.com>,
soren.brinkmann@xilinx.com, linux-mmc@vger.kernel.org,
linux-kernel@vger.kernel.org,
Shawn Lin <shawn.lin@rock-chips.com>
Subject: [RFC PATCH 2/4] mmc: core: implement enhanced strobe support
Date: Thu, 3 Mar 2016 10:36:36 +0800 [thread overview]
Message-ID: <1456972596-8077-1-git-send-email-shawn.lin@rock-chips.com> (raw)
In-Reply-To: <1456972557-7994-1-git-send-email-shawn.lin@rock-chips.com>
Controllers use data strobe line to latch data from devices
under hs400 mode, but not for cmd line. So from emmc 5.1, JEDEC
introduces enhanced strobe mode for latching cmd response from
emmc devices to host controllers. This new feature is optional.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/core/mmc.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/mmc/card.h | 1 +
include/linux/mmc/host.h | 2 ++
include/linux/mmc/mmc.h | 2 ++
4 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 4dbe3df..701ab27 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -585,6 +585,12 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
card->ext_csd.ffu_capable =
(ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) &&
!(ext_csd[EXT_CSD_FW_CONFIG] & 0x1);
+ /*
+ * Enhance Strobe is supported since v5.1 which rev should be
+ * 8 but some eMMC devices can support it with rev 7. So handle
+ * Enhance Strobe here.
+ */
+ card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
}
out:
return err;
@@ -1097,9 +1103,26 @@ static int mmc_select_hs400(struct mmc_card *card)
}
/* Switch card to DDR */
+ val = EXT_CSD_DDR_BUS_WIDTH_8;
+ if (card->ext_csd.strobe_support && mmc_host_enhanced_strobe(host)) {
+ val |= EXT_CSD_BUS_WIDTH_STROBE;
+ /*
+ * Make sure we are in non-enhanced strobe mode before we
+ * actually enable it in ext_csd.
+ */
+ if (host->ops->prepare_enhanced_strobe)
+ err = host->ops->prepare_enhanced_strobe(host, false);
+
+ if (err) {
+ pr_err("%s: unprepare_enhanced strobe failed, err:%d\n",
+ mmc_hostname(host), err);
+ return err;
+ }
+ }
+
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH,
- EXT_CSD_DDR_BUS_WIDTH_8,
+ val,
card->ext_csd.generic_cmd6_time);
if (err) {
pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
@@ -1107,6 +1130,35 @@ static int mmc_select_hs400(struct mmc_card *card)
return err;
}
+ if (card->ext_csd.strobe_support && mmc_host_enhanced_strobe(host)) {
+ /* Controller enable enhanced strobe function */
+ if (host->ops->prepare_enhanced_strobe)
+ err = host->ops->prepare_enhanced_strobe(host, true);
+
+ if (err) {
+ pr_err("%s: prepare enhanced strobe failed, err:%d\n",
+ mmc_hostname(host), err);
+ return err;
+ }
+
+ mmc_set_bus_width(host, MMC_BUS_WIDTH_8);
+ /*
+ * If controller can't handle bus width test,
+ * compare ext_csd previously read in 1 bit mode
+ * against ext_csd at new bus width
+ */
+ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
+ err = mmc_compare_ext_csds(card, MMC_BUS_WIDTH_8);
+ else
+ err = mmc_bus_test(card, MMC_BUS_WIDTH_8);
+
+ if (err) {
+ pr_warn("%s: switch to enhanced strobe failed\n",
+ mmc_hostname(host));
+ return err;
+ }
+ }
+
/* Switch card to HS400 */
val = EXT_CSD_TIMING_HS400 |
card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index eb0151b..22defc2 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -95,6 +95,7 @@ struct mmc_ext_csd {
u8 raw_partition_support; /* 160 */
u8 raw_rpmb_size_mult; /* 168 */
u8 raw_erased_mem_count; /* 181 */
+ u8 strobe_support; /* 184 */
u8 raw_ext_csd_structure; /* 194 */
u8 raw_card_type; /* 196 */
u8 raw_driver_strength; /* 197 */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 2a292b3..8ef3bde 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -132,6 +132,8 @@ struct mmc_host_ops {
/* Prepare HS400 target operating frequency depending host driver */
int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
+ /* Prepare enhanced strobe depending host driver */
+ int (*prepare_enhanced_strobe)(struct mmc_host *host, bool enable);
int (*select_drive_strength)(struct mmc_card *card,
unsigned int max_dtr, int host_drv,
int card_drv, int *drv_type);
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 15f2c4a..593c605 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -297,6 +297,7 @@ struct _mmc_csd {
#define EXT_CSD_PART_CONFIG 179 /* R/W */
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
+#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_POWER_CLASS 187 /* R/W */
#define EXT_CSD_REV 192 /* RO */
@@ -386,6 +387,7 @@ struct _mmc_csd {
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
+#define EXT_CSD_BUS_WIDTH_STROBE BIT(7) /* Enhanced strobe mode */
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
#define EXT_CSD_TIMING_HS 1 /* High speed */
--
2.3.7
next prev parent reply other threads:[~2016-03-03 2:44 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-03 2:35 [RFC PATCH 0/4] Add enhanced strobe support for emmc version 5.1 or later Shawn Lin
2016-03-03 2:36 ` [RFC PATCH 1/4] mmc: core: add cap-enhanced-strobe support Shawn Lin
2016-03-03 12:08 ` Jaehoon Chung
2016-03-04 1:39 ` Shawn Lin
2016-03-03 2:36 ` Shawn Lin [this message]
2016-03-03 13:37 ` [RFC PATCH 2/4] mmc: core: implement enhanced strobe support Adrian Hunter
2016-03-04 2:00 ` Shawn Lin
2016-03-03 2:36 ` [RFC PATCH 3/4] mmc: sdhci: implement enhanced strobe callback Shawn Lin
2016-03-03 2:36 ` [RFC PATCH 4/4] mmc: sdhci-of-arasan: overwrite " Shawn Lin
2016-03-03 11:02 ` Michal Simek
2016-03-03 11:37 ` Shawn Lin
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=1456972596-8077-1-git-send-email-shawn.lin@rock-chips.com \
--to=shawn.lin@rock-chips.com \
--cc=adrian.hunter@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=michal.simek@xilinx.com \
--cc=soren.brinkmann@xilinx.com \
--cc=ulf.hansson@linaro.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®