linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support
@ 2017-02-20  8:03 Ritesh Harjani
  2017-02-20  8:03 ` [RFC PATCH 1/4] Documentation: mmc: add mmc-sleep-awake Ritesh Harjani
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Ritesh Harjani @ 2017-02-20  8:03 UTC (permalink / raw)
  To: ulf.hansson, linux-mmc, adrian.hunter
  Cc: shawn.lin, devicetree, andy.gross, linux-arm-msm, georgi.djakov,
	alex.lemberg, mateusz.nowak, Yuliy.Izrailov, asutoshd,
	david.griego, stummala, venkatg, pramod.gurav, jeremymc,
	linux-kernel, Ritesh Harjani

As per JEDEC spec - CMD5 can be used to awake from sleep mode for emmc.
This patch series provide CMD5(awake) + mmc_partial_init support to resume
mmc card device. This is mainly to reduce the resume time.

This was tested on db410c (emmc with HS200 mode) and MS8996 (emmc with HS400ES)
based internal board. This patch reduced the resume time by ~50% on msm8996
and ~11% on db410c.

As of now this patch series provides a caps (MMC_CAP2_SLEEP_AWAKE) to enable this feature.
Since there is no dependency on host platform for this, we can enable this feature by
default as well. Thoughts?


Ritesh Harjani (4):
  Documentation: mmc: add mmc-sleep-awake
  mmc: core: add mmc-sleep-awake caps
  mmc: mmc: add support for CMD5 awake
  mmc: core: Implement mmc_partial_init during resume

 Documentation/devicetree/bindings/mmc/mmc.txt |   2 +
 drivers/mmc/core/core.c                       |  13 +++
 drivers/mmc/core/core.h                       |   1 +
 drivers/mmc/core/host.c                       |   2 +
 drivers/mmc/core/mmc.c                        | 160 ++++++++++++++++++++++++--
 include/linux/mmc/card.h                      |   3 +
 include/linux/mmc/host.h                      |   2 +
 7 files changed, 176 insertions(+), 7 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH 1/4] Documentation: mmc: add mmc-sleep-awake
  2017-02-20  8:03 [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ritesh Harjani
@ 2017-02-20  8:03 ` Ritesh Harjani
  2017-02-27 19:04   ` Rob Herring
  2017-02-20  8:03 ` [RFC PATCH 2/4] mmc: core: add mmc-sleep-awake caps Ritesh Harjani
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Ritesh Harjani @ 2017-02-20  8:03 UTC (permalink / raw)
  To: ulf.hansson, linux-mmc, adrian.hunter
  Cc: shawn.lin, devicetree, andy.gross, linux-arm-msm, georgi.djakov,
	alex.lemberg, mateusz.nowak, Yuliy.Izrailov, asutoshd,
	david.griego, stummala, venkatg, pramod.gurav, jeremymc,
	linux-kernel, Ritesh Harjani

mmc-sleep-awake enables CMD5 awake feature
& partial_init which can help reduce resume
latency on emmc.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 Documentation/devicetree/bindings/mmc/mmc.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index c7f4a0e..b0df54c 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -53,6 +53,8 @@ Optional properties:
 - no-sdio: controller is limited to send sdio cmd during initialization
 - no-sd: controller is limited to send sd cmd during initialization
 - no-mmc: controller is limited to send mmc cmd during initialization
+- mmc-sleep-awake: eMMC to support awake by CMD5 partial init to reduce resume
+  latency.
 
 *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
 polarity properties, we have to fix the meaning of the "normal" and "inverted"
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 2/4] mmc: core: add mmc-sleep-awake caps
  2017-02-20  8:03 [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ritesh Harjani
  2017-02-20  8:03 ` [RFC PATCH 1/4] Documentation: mmc: add mmc-sleep-awake Ritesh Harjani
@ 2017-02-20  8:03 ` Ritesh Harjani
  2017-02-20  8:03 ` [RFC PATCH 3/4] mmc: mmc: add support for CMD5 awake Ritesh Harjani
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Ritesh Harjani @ 2017-02-20  8:03 UTC (permalink / raw)
  To: ulf.hansson, linux-mmc, adrian.hunter
  Cc: shawn.lin, devicetree, andy.gross, linux-arm-msm, georgi.djakov,
	alex.lemberg, mateusz.nowak, Yuliy.Izrailov, asutoshd,
	david.griego, stummala, venkatg, pramod.gurav, jeremymc,
	linux-kernel, Ritesh Harjani

This patch introduce mmc-sleep-awake for platforms
which want to enable CMD5 awake & partial_init.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/core/host.c  | 2 ++
 include/linux/mmc/host.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 3f8c85d..e798814 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -320,6 +320,8 @@ int mmc_of_parse(struct mmc_host *host)
 		host->caps2 |= MMC_CAP2_NO_SD;
 	if (of_property_read_bool(np, "no-mmc"))
 		host->caps2 |= MMC_CAP2_NO_MMC;
+	if (of_property_read_bool(np, "mmc-sleep-awake"))
+		host->caps2 |= MMC_CAP2_SLEEP_AWAKE;
 
 	host->dsr_req = !of_property_read_u32(np, "dsr", &host->dsr);
 	if (host->dsr_req && (host->dsr & ~0xffff)) {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 83f1c4a..df7882b 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -303,6 +303,7 @@ struct mmc_host {
 #define MMC_CAP2_HS400_ES	(1 << 20)	/* Host supports enhanced strobe */
 #define MMC_CAP2_NO_SD		(1 << 21)	/* Do not send SD commands during initialization */
 #define MMC_CAP2_NO_MMC		(1 << 22)	/* Do not send (e)MMC commands during initialization */
+#define MMC_CAP2_SLEEP_AWAKE	(1 << 23)	/* Use Sleep/Awake (CMD5) */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 3/4] mmc: mmc: add support for CMD5 awake
  2017-02-20  8:03 [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ritesh Harjani
  2017-02-20  8:03 ` [RFC PATCH 1/4] Documentation: mmc: add mmc-sleep-awake Ritesh Harjani
  2017-02-20  8:03 ` [RFC PATCH 2/4] mmc: core: add mmc-sleep-awake caps Ritesh Harjani
@ 2017-02-20  8:03 ` Ritesh Harjani
  2017-02-20  8:03 ` [RFC PATCH 4/4] mmc: core: Implement mmc_partial_init during resume Ritesh Harjani
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Ritesh Harjani @ 2017-02-20  8:03 UTC (permalink / raw)
  To: ulf.hansson, linux-mmc, adrian.hunter
  Cc: shawn.lin, devicetree, andy.gross, linux-arm-msm, georgi.djakov,
	alex.lemberg, mateusz.nowak, Yuliy.Izrailov, asutoshd,
	david.griego, stummala, venkatg, pramod.gurav, jeremymc,
	linux-kernel, Ritesh Harjani

This patch adds CMD5 awake support for emmc.
This will be used to awake emmc from suspend together
with partial_init support to reduce resume latencies.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/core/mmc.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 7fd7228..83bcc86 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1827,7 +1827,7 @@ static int mmc_can_sleep(struct mmc_card *card)
 	return (card && card->ext_csd.rev >= 3);
 }
 
-static int mmc_sleep(struct mmc_host *host)
+static int mmc_sleepawake(struct mmc_host *host, bool sleep)
 {
 	struct mmc_command cmd = {};
 	struct mmc_card *card = host->card;
@@ -1837,13 +1837,16 @@ static int mmc_sleep(struct mmc_host *host)
 	/* Re-tuning can't be done once the card is deselected */
 	mmc_retune_hold(host);
 
-	err = mmc_deselect_cards(host);
-	if (err)
-		goto out_release;
+	if (sleep) {
+		err = mmc_deselect_cards(host);
+		if (err)
+			goto out_release;
+	}
 
 	cmd.opcode = MMC_SLEEP_AWAKE;
 	cmd.arg = card->rca << 16;
-	cmd.arg |= 1 << 15;
+	if (sleep)
+		cmd.arg |= 1 << 15;
 
 	/*
 	 * If the max_busy_timeout of the host is specified, validate it against
@@ -1871,11 +1874,24 @@ static int mmc_sleep(struct mmc_host *host)
 	if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
 		mmc_delay(timeout_ms);
 
+	if (!sleep)
+		err = mmc_select_card(card);
+
 out_release:
 	mmc_retune_release(host);
 	return err;
 }
 
+static int mmc_sleep(struct mmc_host *host)
+{
+	return mmc_sleepawake(host, true);
+}
+
+static int mmc_awake(struct mmc_host *host)
+{
+	return mmc_sleepawake(host, false);
+}
+
 static int mmc_can_poweroff_notify(const struct mmc_card *card)
 {
 	return card &&
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 4/4] mmc: core: Implement mmc_partial_init during resume
  2017-02-20  8:03 [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ritesh Harjani
                   ` (2 preceding siblings ...)
  2017-02-20  8:03 ` [RFC PATCH 3/4] mmc: mmc: add support for CMD5 awake Ritesh Harjani
@ 2017-02-20  8:03 ` Ritesh Harjani
  2017-02-21  7:40   ` Adrian Hunter
  2017-02-21 10:51   ` Ulf Hansson
  2017-02-20 11:39 ` [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ulf Hansson
  2017-02-22  0:55 ` Shawn Lin
  5 siblings, 2 replies; 11+ messages in thread
From: Ritesh Harjani @ 2017-02-20  8:03 UTC (permalink / raw)
  To: ulf.hansson, linux-mmc, adrian.hunter
  Cc: shawn.lin, devicetree, andy.gross, linux-arm-msm, georgi.djakov,
	alex.lemberg, mateusz.nowak, Yuliy.Izrailov, asutoshd,
	david.griego, stummala, venkatg, pramod.gurav, jeremymc,
	linux-kernel, Ritesh Harjani, Talel Shenhar, Maya Erez

This patch adds mmc_partial_init functionality
combining with CMD5 awake feature to reduce resume
latency for emmc.

This is not enabled for HS400 mode, since tuning
in HS400 is required to be done in HS200 timing.

Signed-off-by: Talel Shenhar <tatias@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/core/core.c  |  13 +++++
 drivers/mmc/core/core.h  |   1 +
 drivers/mmc/core/mmc.c   | 134 ++++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/mmc/card.h |   3 ++
 include/linux/mmc/host.h |   1 +
 5 files changed, 150 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 926e0fd..4bbe3eb 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1197,6 +1197,19 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
 	mmc_set_ios(host);
 }
 
+void mmc_set_init_state(struct mmc_host *host)
+{
+	host->ios.bus_mode = host->cached_ios.bus_mode;
+	host->ios.bus_width = host->cached_ios.bus_width;
+	host->ios.timing = host->cached_ios.timing;
+	if (host->card &&
+	    host->card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES &&
+	    host->cached_ios.timing == MMC_TIMING_MMC_HS400)
+		host->ios.enhanced_strobe = true;
+
+	mmc_set_ios(host);
+}
+
 /*
  * Set initial state after a power cycle or a hw_reset.
  */
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 55f543f..9476a89 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -58,6 +58,7 @@ int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
 void mmc_power_off(struct mmc_host *host);
 void mmc_power_cycle(struct mmc_host *host, u32 ocr);
 void mmc_set_initial_state(struct mmc_host *host);
+void mmc_set_init_state(struct mmc_host *host);
 
 static inline void mmc_delay(unsigned int ms)
 {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 83bcc86..f7c244c 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1827,6 +1827,28 @@ static int mmc_can_sleep(struct mmc_card *card)
 	return (card && card->ext_csd.rev >= 3);
 }
 
+static int mmc_can_sleepawake_mode(struct mmc_host *host)
+{
+	/*
+	 * Disabled for HS400 mode since it requires tuning
+	 * to be done in HS200 timing and then switching
+	 * to HS400 mode.
+	 */
+	switch (host->cached_ios.timing) {
+	case MMC_TIMING_MMC_HS400:
+		if (!(host->card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES))
+			return 0;
+	default:
+		return 1;
+	}
+}
+
+static int mmc_can_sleepawake(struct mmc_host *host)
+{
+	return (host && host->caps2 & MMC_CAP2_SLEEP_AWAKE &&
+		mmc_can_sleep(host->card) && mmc_can_sleepawake_mode(host));
+}
+
 static int mmc_sleepawake(struct mmc_host *host, bool sleep)
 {
 	struct mmc_command cmd = {};
@@ -1964,6 +1986,100 @@ static void mmc_detect(struct mmc_host *host)
 	}
 }
 
+static int mmc_cache_card_ext_csd(struct mmc_host *host)
+{
+	int err;
+	u8 *ext_csd;
+	struct mmc_card *card = host->card;
+
+	err = mmc_get_ext_csd(card, &ext_csd);
+	if (err || !ext_csd) {
+		pr_err("%s: %s: mmc_get_ext_csd failed (%d)\n",
+		       mmc_hostname(host), __func__, err);
+		return err;
+	}
+
+	/* only cache read/write fields that the sw changes */
+	card->ext_csd.raw_ext_csd_cache_ctrl = ext_csd[EXT_CSD_CACHE_CTRL];
+	card->ext_csd.raw_ext_csd_bus_width = ext_csd[EXT_CSD_BUS_WIDTH];
+	card->ext_csd.raw_ext_csd_hs_timing = ext_csd[EXT_CSD_HS_TIMING];
+	kfree(ext_csd);
+	return 0;
+}
+
+static int mmc_test_awake_ext_csd(struct mmc_host *host)
+{
+	int err;
+	u8 *ext_csd;
+	struct mmc_card *card = host->card;
+
+	return 0;
+	err = mmc_get_ext_csd(card, &ext_csd);
+	if (err) {
+		pr_err("%s: %s: mmc_get_ext_csd failed (%d)\n",
+		       mmc_hostname(host), __func__, err);
+		return err;
+	}
+
+	/* only compare read/write fields that the sw changes */
+	pr_debug("%s: %s: type(cached:current) cache_ctrl(%d:%d) bus_width (%d:%d) timing(%d:%d)\n",
+		 mmc_hostname(host), __func__,
+		 card->ext_csd.raw_ext_csd_cache_ctrl,
+		 ext_csd[EXT_CSD_CACHE_CTRL],
+		 card->ext_csd.raw_ext_csd_bus_width,
+		 ext_csd[EXT_CSD_BUS_WIDTH],
+		 card->ext_csd.raw_ext_csd_hs_timing,
+		 ext_csd[EXT_CSD_HS_TIMING]);
+
+	err = !((card->ext_csd.raw_ext_csd_cache_ctrl ==
+			ext_csd[EXT_CSD_CACHE_CTRL]) &&
+		(card->ext_csd.raw_ext_csd_bus_width ==
+			ext_csd[EXT_CSD_BUS_WIDTH]) &&
+		(card->ext_csd.raw_ext_csd_hs_timing ==
+			ext_csd[EXT_CSD_HS_TIMING]));
+
+	kfree(ext_csd);
+	return err;
+}
+
+static int mmc_partial_init(struct mmc_host *host)
+{
+	int err = 0;
+	struct mmc_card *card = host->card;
+
+	mmc_set_init_state(host);
+	mmc_set_clock(host, host->cached_ios.clock);
+	if (mmc_card_hs400(card)) {
+		if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) {
+			if (host->ops->hs400_enhanced_strobe)
+				host->ops->hs400_enhanced_strobe(host,
+								 &host->ios);
+		}
+	} else if (mmc_card_hs200(card)) {
+		err = mmc_hs200_tuning(card);
+		if (err)
+			pr_warn("%s: %s: tuning execution failed (%d)\n",
+				mmc_hostname(host), __func__, err);
+	}
+
+	/*
+	 * The ext_csd is read to make sure the card did not went through
+	 * Power-failure during sleep period.
+	 * A subset of the W/E_P, W/C_P register will be tested. In case
+	 * these registers values are different from the values that were
+	 * cached during suspend, we will conclude that a Power-failure occurred
+	 * and will do full initialization sequence.
+	 */
+	err = mmc_test_awake_ext_csd(host);
+	if (err) {
+		pr_err("%s: %s: fail on ext_csd read (%d)\n",
+		       mmc_hostname(host), __func__, err);
+		goto out;
+	}
+out:
+	return err;
+}
+
 static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
 {
 	int err = 0;
@@ -1988,7 +2104,11 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
 	if (mmc_can_poweroff_notify(host->card) &&
 		((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend))
 		err = mmc_poweroff_notify(host->card, notify_type);
-	else if (mmc_can_sleep(host->card))
+	else if (mmc_can_sleepawake(host)) {
+		memcpy(&host->cached_ios, &host->ios, sizeof(host->cached_ios));
+		mmc_cache_card_ext_csd(host);
+		err = mmc_sleep(host);
+	} else if (mmc_can_sleep(host->card))
 		err = mmc_sleep(host);
 	else if (!mmc_host_is_spi(host))
 		err = mmc_deselect_cards(host);
@@ -2032,7 +2152,17 @@ static int _mmc_resume(struct mmc_host *host)
 		goto out;
 
 	mmc_power_up(host, host->card->ocr);
-	err = mmc_init_card(host, host->card->ocr, host->card);
+	if (mmc_can_sleepawake(host)) {
+		err = mmc_awake(host);
+		if (!err)
+			err = mmc_partial_init(host);
+		if (err)
+			pr_err("%s: awake failed (%d), fallback to full init\n",
+			       mmc_hostname(host), err);
+	}
+	if (err || !mmc_can_sleepawake(host))
+		err = mmc_init_card(host, host->card->ocr, host->card);
+
 	mmc_card_clr_suspended(host->card);
 
 out:
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 77e61e0..9aa2c97 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -93,11 +93,14 @@ struct mmc_ext_csd {
 	unsigned int		cmdq_depth;	/* Command Queue depth */
 #define MMC_FIRMWARE_LEN 8
 	u8			fwrev[MMC_FIRMWARE_LEN];  /* FW version */
+	u8			raw_ext_csd_cache_ctrl;	/* 33 */
 	u8			raw_exception_status;	/* 54 */
 	u8			raw_partition_support;	/* 160 */
 	u8			raw_rpmb_size_mult;	/* 168 */
 	u8			raw_erased_mem_count;	/* 181 */
+	u8			raw_ext_csd_bus_width;	/* 183 */
 	u8			strobe_support;		/* 184 */
+	u8			raw_ext_csd_hs_timing;	/* 185 */
 	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 df7882b..c89407c 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -320,6 +320,7 @@ struct mmc_host {
 	spinlock_t		lock;		/* lock for claim and bus ops */
 
 	struct mmc_ios		ios;		/* current io bus settings */
+	struct mmc_ios		cached_ios;
 
 	/* group bitfields together to minimize padding */
 	unsigned int		use_spi_crc:1;
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support
  2017-02-20  8:03 [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ritesh Harjani
                   ` (3 preceding siblings ...)
  2017-02-20  8:03 ` [RFC PATCH 4/4] mmc: core: Implement mmc_partial_init during resume Ritesh Harjani
@ 2017-02-20 11:39 ` Ulf Hansson
  2017-02-20 13:04   ` Ritesh Harjani
  2017-02-22  0:55 ` Shawn Lin
  5 siblings, 1 reply; 11+ messages in thread
From: Ulf Hansson @ 2017-02-20 11:39 UTC (permalink / raw)
  To: Ritesh Harjani
  Cc: linux-mmc, Adrian Hunter, Shawn Lin, devicetree, Andy Gross,
	linux-arm-msm, Georgi Djakov, Alex Lemberg, Mateusz Nowak,
	Yuliy Izrailov, Asutosh Das, David Griego, Sahitya Tummala,
	Venkat Gopalakrishnan, Pramod Gurav, jeremymc, linux-kernel

On 20 February 2017 at 09:03, Ritesh Harjani <riteshh@codeaurora.org> wrote:
> As per JEDEC spec - CMD5 can be used to awake from sleep mode for emmc.
> This patch series provide CMD5(awake) + mmc_partial_init support to resume
> mmc card device. This is mainly to reduce the resume time.

I assume with "resume time" you don't mean "system PM resume time"?

The current approach we have for MMC is to postpone system PM resume
of the card until it's actually needed, thus via runtime PM instead.
Then the time it takes to re-initialize the eMMC don't affect the
system PM resume time at all.

Therefore I am wondering about how big of a problem this really is. Is
there a specific use case you are optimizing for?

>
> This was tested on db410c (emmc with HS200 mode) and MS8996 (emmc with HS400ES)
> based internal board. This patch reduced the resume time by ~50% on msm8996
> and ~11% on db410c.

The improved behaviour in percentage is very interesting, but I would
also like to see real numbers.

Moreover, I would like to know what kind of mechanism the
corresponding host drivers/controllers are using for card busy
detection?

>
> As of now this patch series provides a caps (MMC_CAP2_SLEEP_AWAKE) to enable this feature.
> Since there is no dependency on host platform for this, we can enable this feature by
> default as well. Thoughts?

I will look into the series in more detail, however we must not add a
corresponding DT binding for this as this isn't a HW configuration. I
guess what you need to know is that VCCQ stays powered on when the
card is a sleep, else waking up with CMD5 won't work
(MMC_CAP_FULL_PWR_CYCLE).

The current main concern I can think of, is whether the added
complexity to the wakeup path can be justified for the improved
behaviour.

>
>
> Ritesh Harjani (4):
>   Documentation: mmc: add mmc-sleep-awake
>   mmc: core: add mmc-sleep-awake caps
>   mmc: mmc: add support for CMD5 awake
>   mmc: core: Implement mmc_partial_init during resume
>
>  Documentation/devicetree/bindings/mmc/mmc.txt |   2 +
>  drivers/mmc/core/core.c                       |  13 +++
>  drivers/mmc/core/core.h                       |   1 +
>  drivers/mmc/core/host.c                       |   2 +
>  drivers/mmc/core/mmc.c                        | 160 ++++++++++++++++++++++++--
>  include/linux/mmc/card.h                      |   3 +
>  include/linux/mmc/host.h                      |   2 +
>  7 files changed, 176 insertions(+), 7 deletions(-)
>
> --
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project.
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support
  2017-02-20 11:39 ` [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ulf Hansson
@ 2017-02-20 13:04   ` Ritesh Harjani
  0 siblings, 0 replies; 11+ messages in thread
From: Ritesh Harjani @ 2017-02-20 13:04 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Adrian Hunter, Shawn Lin, devicetree, Andy Gross,
	linux-arm-msm, Georgi Djakov, Alex Lemberg, Mateusz Nowak,
	Yuliy Izrailov, Asutosh Das, David Griego, Sahitya Tummala,
	Venkat Gopalakrishnan, Pramod Gurav, jeremymc, linux-kernel

Hi Ulf,

On 2/20/2017 5:09 PM, Ulf Hansson wrote:
> On 20 February 2017 at 09:03, Ritesh Harjani <riteshh@codeaurora.org> wrote:
>> As per JEDEC spec - CMD5 can be used to awake from sleep mode for emmc.
>> This patch series provide CMD5(awake) + mmc_partial_init support to resume
>> mmc card device. This is mainly to reduce the resume time.
>
> I assume with "resume time" you don't mean "system PM resume time"?
I meant mmc_runtime_resume time which will be accounted only in MMC card 
run-time resume now.


>
> The current approach we have for MMC is to postpone system PM resume
> of the card until it's actually needed, thus via runtime PM instead.
> Then the time it takes to re-initialize the eMMC don't affect the
> system PM resume time at all.
>
> Therefore I am wondering about how big of a problem this really is. Is
> there a specific use case you are optimizing for?
In general MMC card resume time will be optimized.

>
>>
>> This was tested on db410c (emmc with HS200 mode) and MS8996 (emmc with HS400ES)
>> based internal board. This patch reduced the resume time by ~50% on msm8996
>> and ~11% on db410c.
Sorry, I did not enable MMC_CAP_WAIT_WHILE_BUSY on db410c. That's why we 
see 11% improvement only. After I enabled this cap, I see ~47% 
improvement in mmc_runtime_resume on db410c.


>
> The improved behaviour in percentage is very interesting, but I would
> also like to see real numbers.

<DB410c>
1. ~110ms without the patch on db410c (with MMC_CAP_WAIT_WHILE_BUSY)

2. ~97ms with the patch on db410c (w/o enabling MMC_CAP_WAIT_WHILE_BUSY)

3. ~58ms with the patch (with MMC_CAP_WAIT_WHILE_BUSY capability).= ~47%

<MSM8996>
1. ~142ms without the patch on msm8996 (with MMC_CAP_WAIT_WHILE_BUSY)

2. ~50ms with the patch on msm8996. (with MMC_CAP_WAIT_WHILE_BUSY)= ~60%

>
> Moreover, I would like to know what kind of mechanism the
> corresponding host drivers/controllers are using for card busy
> detection?
These controllers have MMC_CAP_WAIT_WHILE_BUSY capability enabled.

I have tested with below caps.

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 10cdc84..2da9c4e 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1283,6 +1283,9 @@ static int sdhci_msm_probe(struct platform_device 
*pdev)
         pm_runtime_use_autosuspend(&pdev->dev);

         host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning;
+       host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
+       host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM;
+       host->mmc->caps2 |= MMC_CAP2_SLEEP_AWAKE;
         ret = sdhci_add_host(host);
         if (ret)
                 goto pm_runtime_disable;


>
>>
>> As of now this patch series provides a caps (MMC_CAP2_SLEEP_AWAKE) to enable this feature.
>> Since there is no dependency on host platform for this, we can enable this feature by
>> default as well. Thoughts?
>
> I will look into the series in more detail, however we must not add a
Sure, please let me know your feedback.

> corresponding DT binding for this as this isn't a HW configuration. I
> guess what you need to know is that VCCQ stays powered on when the
> card is a sleep, else waking up with CMD5 won't work
> (MMC_CAP_FULL_PWR_CYCLE).
Ok.

>
> The current main concern I can think of, is whether the added
> complexity to the wakeup path can be justified for the improved
> behaviour.
This may not be very complex actually.


>
>>
>>
>> Ritesh Harjani (4):
>>   Documentation: mmc: add mmc-sleep-awake
>>   mmc: core: add mmc-sleep-awake caps
>>   mmc: mmc: add support for CMD5 awake
>>   mmc: core: Implement mmc_partial_init during resume
>>
>>  Documentation/devicetree/bindings/mmc/mmc.txt |   2 +
>>  drivers/mmc/core/core.c                       |  13 +++
>>  drivers/mmc/core/core.h                       |   1 +
>>  drivers/mmc/core/host.c                       |   2 +
>>  drivers/mmc/core/mmc.c                        | 160 ++++++++++++++++++++++++--
>>  include/linux/mmc/card.h                      |   3 +
>>  include/linux/mmc/host.h                      |   2 +
>>  7 files changed, 176 insertions(+), 7 deletions(-)
>>
>> --
>> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>> a Linux Foundation Collaborative Project.
>>
>
> Kind regards
> Uffe
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 4/4] mmc: core: Implement mmc_partial_init during resume
  2017-02-20  8:03 ` [RFC PATCH 4/4] mmc: core: Implement mmc_partial_init during resume Ritesh Harjani
@ 2017-02-21  7:40   ` Adrian Hunter
  2017-02-21 10:51   ` Ulf Hansson
  1 sibling, 0 replies; 11+ messages in thread
From: Adrian Hunter @ 2017-02-21  7:40 UTC (permalink / raw)
  To: Ritesh Harjani, ulf.hansson, linux-mmc
  Cc: shawn.lin, devicetree, andy.gross, linux-arm-msm, georgi.djakov,
	alex.lemberg, mateusz.nowak, Yuliy.Izrailov, asutoshd,
	david.griego, stummala, venkatg, pramod.gurav, jeremymc,
	linux-kernel, Talel Shenhar, Maya Erez

On 20/02/17 10:03, Ritesh Harjani wrote:
> This patch adds mmc_partial_init functionality
> combining with CMD5 awake feature to reduce resume
> latency for emmc.
> 
> This is not enabled for HS400 mode, since tuning
> in HS400 is required to be done in HS200 timing.

How does that matter?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 4/4] mmc: core: Implement mmc_partial_init during resume
  2017-02-20  8:03 ` [RFC PATCH 4/4] mmc: core: Implement mmc_partial_init during resume Ritesh Harjani
  2017-02-21  7:40   ` Adrian Hunter
@ 2017-02-21 10:51   ` Ulf Hansson
  1 sibling, 0 replies; 11+ messages in thread
From: Ulf Hansson @ 2017-02-21 10:51 UTC (permalink / raw)
  To: Ritesh Harjani
  Cc: linux-mmc, Adrian Hunter, Shawn Lin, devicetree, Andy Gross,
	linux-arm-msm, Georgi Djakov, Alex Lemberg, Mateusz Nowak,
	Yuliy Izrailov, Asutosh Das, David Griego, Sahitya Tummala,
	Venkat Gopalakrishnan, Pramod Gurav, jeremymc, linux-kernel,
	Talel Shenhar, Maya Erez

On 20 February 2017 at 09:03, Ritesh Harjani <riteshh@codeaurora.org> wrote:
> This patch adds mmc_partial_init functionality
> combining with CMD5 awake feature to reduce resume
> latency for emmc.
>
> This is not enabled for HS400 mode, since tuning
> in HS400 is required to be done in HS200 timing.
>
> Signed-off-by: Talel Shenhar <tatias@codeaurora.org>
> Signed-off-by: Maya Erez <merez@codeaurora.org>
> Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
> Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
> ---
>  drivers/mmc/core/core.c  |  13 +++++
>  drivers/mmc/core/core.h  |   1 +
>  drivers/mmc/core/mmc.c   | 134 ++++++++++++++++++++++++++++++++++++++++++++++-
>  include/linux/mmc/card.h |   3 ++
>  include/linux/mmc/host.h |   1 +
>  5 files changed, 150 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 926e0fd..4bbe3eb 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -1197,6 +1197,19 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
>         mmc_set_ios(host);
>  }
>
> +void mmc_set_init_state(struct mmc_host *host)
> +{
> +       host->ios.bus_mode = host->cached_ios.bus_mode;
> +       host->ios.bus_width = host->cached_ios.bus_width;
> +       host->ios.timing = host->cached_ios.timing;

Is this really sufficient? Isn't there more to restore from the cached ios?

> +       if (host->card &&
> +           host->card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES &&
> +           host->cached_ios.timing == MMC_TIMING_MMC_HS400)
> +               host->ios.enhanced_strobe = true;

Why don't you check the cached value for enhanced_strobe instead?

> +
> +       mmc_set_ios(host);
> +}
> +
>  /*
>   * Set initial state after a power cycle or a hw_reset.
>   */
> diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
> index 55f543f..9476a89 100644
> --- a/drivers/mmc/core/core.h
> +++ b/drivers/mmc/core/core.h
> @@ -58,6 +58,7 @@ int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
>  void mmc_power_off(struct mmc_host *host);
>  void mmc_power_cycle(struct mmc_host *host, u32 ocr);
>  void mmc_set_initial_state(struct mmc_host *host);
> +void mmc_set_init_state(struct mmc_host *host);
>
>  static inline void mmc_delay(unsigned int ms)
>  {
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 83bcc86..f7c244c 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -1827,6 +1827,28 @@ static int mmc_can_sleep(struct mmc_card *card)
>         return (card && card->ext_csd.rev >= 3);
>  }
>
> +static int mmc_can_sleepawake_mode(struct mmc_host *host)
> +{
> +       /*
> +        * Disabled for HS400 mode since it requires tuning
> +        * to be done in HS200 timing and then switching
> +        * to HS400 mode.
> +        */
> +       switch (host->cached_ios.timing) {
> +       case MMC_TIMING_MMC_HS400:
> +               if (!(host->card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES))
> +                       return 0;

I don't get this? Could you elaborate why this case doesn’t work?

> +       default:
> +               return 1;
> +       }
> +}
> +
> +static int mmc_can_sleepawake(struct mmc_host *host)
> +{
> +       return (host && host->caps2 & MMC_CAP2_SLEEP_AWAKE &&

As I stated in the response to the cover letter, we could check for
MMC_CAP2_FULL_PWR_CYCLE instead.

Although, the problem with that would be if the host/soc supports a
full power cycle, but still doesn't set MMC_CAP2_FULL_PWR_CYCLE. If
that is the case, you shouldn't be using CMD5 to wake up the card from
sleep as it won't work.

This complexity, is one of the reasons to why we so far have chosen to
use CMD0 to wakeup the card from sleep. Because we know it is *always*
going to work.

I guess if we implement a fallback method of using CMD0 when CMD5
fails, perhaps that would be acceptable...

However, trying out CMD5 first and thus spend time on this
re-initialization sequence, then finding out that it fails will of
course be a waste of time.

> +               mmc_can_sleep(host->card) && mmc_can_sleepawake_mode(host));
> +}
> +
>  static int mmc_sleepawake(struct mmc_host *host, bool sleep)
>  {
>         struct mmc_command cmd = {};
> @@ -1964,6 +1986,100 @@ static void mmc_detect(struct mmc_host *host)
>         }
>  }
>
> +static int mmc_cache_card_ext_csd(struct mmc_host *host)
> +{
> +       int err;
> +       u8 *ext_csd;
> +       struct mmc_card *card = host->card;
> +
> +       err = mmc_get_ext_csd(card, &ext_csd);
> +       if (err || !ext_csd) {
> +               pr_err("%s: %s: mmc_get_ext_csd failed (%d)\n",
> +                      mmc_hostname(host), __func__, err);
> +               return err;
> +       }
> +
> +       /* only cache read/write fields that the sw changes */
> +       card->ext_csd.raw_ext_csd_cache_ctrl = ext_csd[EXT_CSD_CACHE_CTRL];
> +       card->ext_csd.raw_ext_csd_bus_width = ext_csd[EXT_CSD_BUS_WIDTH];
> +       card->ext_csd.raw_ext_csd_hs_timing = ext_csd[EXT_CSD_HS_TIMING];
> +       kfree(ext_csd);
> +       return 0;
> +}
> +
> +static int mmc_test_awake_ext_csd(struct mmc_host *host)
> +{
> +       int err;
> +       u8 *ext_csd;
> +       struct mmc_card *card = host->card;
> +
> +       return 0;
> +       err = mmc_get_ext_csd(card, &ext_csd);
> +       if (err) {
> +               pr_err("%s: %s: mmc_get_ext_csd failed (%d)\n",
> +                      mmc_hostname(host), __func__, err);
> +               return err;
> +       }
> +
> +       /* only compare read/write fields that the sw changes */
> +       pr_debug("%s: %s: type(cached:current) cache_ctrl(%d:%d) bus_width (%d:%d) timing(%d:%d)\n",
> +                mmc_hostname(host), __func__,
> +                card->ext_csd.raw_ext_csd_cache_ctrl,
> +                ext_csd[EXT_CSD_CACHE_CTRL],
> +                card->ext_csd.raw_ext_csd_bus_width,
> +                ext_csd[EXT_CSD_BUS_WIDTH],
> +                card->ext_csd.raw_ext_csd_hs_timing,
> +                ext_csd[EXT_CSD_HS_TIMING]);
> +
> +       err = !((card->ext_csd.raw_ext_csd_cache_ctrl ==
> +                       ext_csd[EXT_CSD_CACHE_CTRL]) &&
> +               (card->ext_csd.raw_ext_csd_bus_width ==
> +                       ext_csd[EXT_CSD_BUS_WIDTH]) &&
> +               (card->ext_csd.raw_ext_csd_hs_timing ==
> +                       ext_csd[EXT_CSD_HS_TIMING]));
> +
> +       kfree(ext_csd);
> +       return err;
> +}
> +
> +static int mmc_partial_init(struct mmc_host *host)
> +{
> +       int err = 0;
> +       struct mmc_card *card = host->card;
> +
> +       mmc_set_init_state(host);
> +       mmc_set_clock(host, host->cached_ios.clock);
> +       if (mmc_card_hs400(card)) {
> +               if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) {
> +                       if (host->ops->hs400_enhanced_strobe)
> +                               host->ops->hs400_enhanced_strobe(host,
> +                                                                &host->ios);
> +               }
> +       } else if (mmc_card_hs200(card)) {
> +               err = mmc_hs200_tuning(card);
> +               if (err)
> +                       pr_warn("%s: %s: tuning execution failed (%d)\n",
> +                               mmc_hostname(host), __func__, err);
> +       }
> +
> +       /*
> +        * The ext_csd is read to make sure the card did not went through
> +        * Power-failure during sleep period.
> +        * A subset of the W/E_P, W/C_P register will be tested. In case
> +        * these registers values are different from the values that were
> +        * cached during suspend, we will conclude that a Power-failure occurred
> +        * and will do full initialization sequence.
> +        */
> +       err = mmc_test_awake_ext_csd(host);

If the card is power cycled (in other words, VCCQ is powered off) the
card won't respond properly on a CMD5 to wakeup from sleep.

Then, why do we need to validate the EXT_CSD? I don't get it.


> +       if (err) {
> +               pr_err("%s: %s: fail on ext_csd read (%d)\n",
> +                      mmc_hostname(host), __func__, err);
> +               goto out;
> +       }
> +out:
> +       return err;
> +}
> +
>  static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
>  {
>         int err = 0;
> @@ -1988,7 +2104,11 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
>         if (mmc_can_poweroff_notify(host->card) &&
>                 ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend))
>                 err = mmc_poweroff_notify(host->card, notify_type);
> -       else if (mmc_can_sleep(host->card))
> +       else if (mmc_can_sleepawake(host)) {
> +               memcpy(&host->cached_ios, &host->ios, sizeof(host->cached_ios));
> +               mmc_cache_card_ext_csd(host);
> +               err = mmc_sleep(host);
> +       } else if (mmc_can_sleep(host->card))
>                 err = mmc_sleep(host);
>         else if (!mmc_host_is_spi(host))
>                 err = mmc_deselect_cards(host);

So, __mmc_suspend() calls mmc_power_off() which resets the ios
settings and power off the card.

Then in _mmc_resume() you restore those settings, which seems like it
could work....


> @@ -2032,7 +2152,17 @@ static int _mmc_resume(struct mmc_host *host)
>                 goto out;
>
>         mmc_power_up(host, host->card->ocr);
> -       err = mmc_init_card(host, host->card->ocr, host->card);
> +       if (mmc_can_sleepawake(host)) {
> +               err = mmc_awake(host);

... however this looks suspiciously wrong. Should you really send a
CMD5 to wakeup the card without first restoring the cached ios
settings?

> +               if (!err)
> +                       err = mmc_partial_init(host);
> +               if (err)
> +                       pr_err("%s: awake failed (%d), fallback to full init\n",
> +                              mmc_hostname(host), err);
> +       }
> +       if (err || !mmc_can_sleepawake(host))
> +               err = mmc_init_card(host, host->card->ocr, host->card);
> +
>         mmc_card_clr_suspended(host->card);
>
>  out:
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 77e61e0..9aa2c97 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -93,11 +93,14 @@ struct mmc_ext_csd {
>         unsigned int            cmdq_depth;     /* Command Queue depth */
>  #define MMC_FIRMWARE_LEN 8
>         u8                      fwrev[MMC_FIRMWARE_LEN];  /* FW version */
> +       u8                      raw_ext_csd_cache_ctrl; /* 33 */
>         u8                      raw_exception_status;   /* 54 */
>         u8                      raw_partition_support;  /* 160 */
>         u8                      raw_rpmb_size_mult;     /* 168 */
>         u8                      raw_erased_mem_count;   /* 181 */
> +       u8                      raw_ext_csd_bus_width;  /* 183 */
>         u8                      strobe_support;         /* 184 */
> +       u8                      raw_ext_csd_hs_timing;  /* 185 */
>         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 df7882b..c89407c 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -320,6 +320,7 @@ struct mmc_host {
>         spinlock_t              lock;           /* lock for claim and bus ops */
>
>         struct mmc_ios          ios;            /* current io bus settings */
> +       struct mmc_ios          cached_ios;
>
>         /* group bitfields together to minimize padding */
>         unsigned int            use_spi_crc:1;
> --
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project.
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support
  2017-02-20  8:03 [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ritesh Harjani
                   ` (4 preceding siblings ...)
  2017-02-20 11:39 ` [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ulf Hansson
@ 2017-02-22  0:55 ` Shawn Lin
  5 siblings, 0 replies; 11+ messages in thread
From: Shawn Lin @ 2017-02-22  0:55 UTC (permalink / raw)
  To: Ritesh Harjani, adrian.hunter
  Cc: ulf.hansson, linux-mmc, shawn.lin, devicetree, andy.gross,
	linux-arm-msm, georgi.djakov, alex.lemberg, mateusz.nowak,
	Yuliy.Izrailov, asutoshd, david.griego, stummala, venkatg,
	pramod.gurav, jeremymc, linux-kernel

Hi Ritesh,

On 2017/2/20 16:03, Ritesh Harjani wrote:
> As per JEDEC spec - CMD5 can be used to awake from sleep mode for emmc.
> This patch series provide CMD5(awake) + mmc_partial_init support to resume
> mmc card device. This is mainly to reduce the resume time.
>

For modem eMMC devices which support vccq to be 1v8, you patch seem to
work fine but that didn't work for some eMMCs that only support 3v3
vccq, for instance, some older v4.41 eMMC devices.

Also, the spec didn't clearly have a statement about the fact that the
partial init should work if keeping vqmmc.

So finally you should have to add a fallback method once the partial
init doesn't work well. In the point, this policy is not just host
specified, but also eMMC device specified. So I guess this is why you
expose a new DT property here instead?!


> This was tested on db410c (emmc with HS200 mode) and MS8996 (emmc with HS400ES)
> based internal board. This patch reduced the resume time by ~50% on msm8996
> and ~11% on db410c.
>
> As of now this patch series provides a caps (MMC_CAP2_SLEEP_AWAKE) to enable this feature.
> Since there is no dependency on host platform for this, we can enable this feature by
> default as well. Thoughts?
>
>
> Ritesh Harjani (4):
>   Documentation: mmc: add mmc-sleep-awake
>   mmc: core: add mmc-sleep-awake caps
>   mmc: mmc: add support for CMD5 awake
>   mmc: core: Implement mmc_partial_init during resume
>
>  Documentation/devicetree/bindings/mmc/mmc.txt |   2 +
>  drivers/mmc/core/core.c                       |  13 +++
>  drivers/mmc/core/core.h                       |   1 +
>  drivers/mmc/core/host.c                       |   2 +
>  drivers/mmc/core/mmc.c                        | 160 ++++++++++++++++++++++++--
>  include/linux/mmc/card.h                      |   3 +
>  include/linux/mmc/host.h                      |   2 +
>  7 files changed, 176 insertions(+), 7 deletions(-)
>


-- 
Best Regards
Shawn Lin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 1/4] Documentation: mmc: add mmc-sleep-awake
  2017-02-20  8:03 ` [RFC PATCH 1/4] Documentation: mmc: add mmc-sleep-awake Ritesh Harjani
@ 2017-02-27 19:04   ` Rob Herring
  0 siblings, 0 replies; 11+ messages in thread
From: Rob Herring @ 2017-02-27 19:04 UTC (permalink / raw)
  To: Ritesh Harjani
  Cc: ulf.hansson, linux-mmc, adrian.hunter, shawn.lin, devicetree,
	andy.gross, linux-arm-msm, georgi.djakov, alex.lemberg,
	mateusz.nowak, Yuliy.Izrailov, asutoshd, david.griego, stummala,
	venkatg, pramod.gurav, jeremymc, linux-kernel

On Mon, Feb 20, 2017 at 01:33:09PM +0530, Ritesh Harjani wrote:
> mmc-sleep-awake enables CMD5 awake feature
> & partial_init which can help reduce resume
> latency on emmc.
> 
> Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
> ---
>  Documentation/devicetree/bindings/mmc/mmc.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
> index c7f4a0e..b0df54c 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc.txt
> +++ b/Documentation/devicetree/bindings/mmc/mmc.txt
> @@ -53,6 +53,8 @@ Optional properties:
>  - no-sdio: controller is limited to send sdio cmd during initialization
>  - no-sd: controller is limited to send sd cmd during initialization
>  - no-mmc: controller is limited to send mmc cmd during initialization
> +- mmc-sleep-awake: eMMC to support awake by CMD5 partial init to reduce resume
> +  latency.

This is a feature of the controller or card? If a card, this should be 
in a card node probably.

Is there a better name that matches the h/w feature?

Rob

>  
>  *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
>  polarity properties, we have to fix the meaning of the "normal" and "inverted"
> -- 
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
> a Linux Foundation Collaborative Project.
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2017-02-27 19:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-20  8:03 [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ritesh Harjani
2017-02-20  8:03 ` [RFC PATCH 1/4] Documentation: mmc: add mmc-sleep-awake Ritesh Harjani
2017-02-27 19:04   ` Rob Herring
2017-02-20  8:03 ` [RFC PATCH 2/4] mmc: core: add mmc-sleep-awake caps Ritesh Harjani
2017-02-20  8:03 ` [RFC PATCH 3/4] mmc: mmc: add support for CMD5 awake Ritesh Harjani
2017-02-20  8:03 ` [RFC PATCH 4/4] mmc: core: Implement mmc_partial_init during resume Ritesh Harjani
2017-02-21  7:40   ` Adrian Hunter
2017-02-21 10:51   ` Ulf Hansson
2017-02-20 11:39 ` [RFC PATCH 0/4] mmc: core: Provide CMD5 awake and partial_init support Ulf Hansson
2017-02-20 13:04   ` Ritesh Harjani
2017-02-22  0:55 ` Shawn Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).