Skip to contentSkip to conversation

mmc: implemented eMMC4.4 hardware reset feature in core layer

PATCH In review Chuanxiao.Dong 1 participant 1 message Nov 2, 2010 MMC, SD and SDIO

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/2 mmc: implemented eMMC4.4 hardware reset feature in core layer

Quoted 1 line

From 80260a0e193a5d0f428afaebb69bcf1790d6e217 Mon Sep 17 00:00:00 2001

From: Chuanxiao Dong <[email protected]>
Date: Tue, 2 Nov 2010 20:39:58 +0800
Subject: [PATCH 1/2] mmc: implemented eMMC4.4 hardware reset feature in mmc core layer

When core layer detect a data timeout error, core driver need to first reset eMMC card and then do a reinit for card. After that, posts the original timeout error to mmc block layer.

1. enable hardware reset feature: to enable hardware reset feature, mmc driver need to set RST_n_function bit in ext_csd register. But this bit is onetime programmable, not sure whether it is suitable for driver to set this bit.

2. The reset part was resvered for host controller to implement.

3. The reinit card part was implemented.

---
 drivers/mmc/core/core.c  |   27 +++++++++++++++++++++++++++
 drivers/mmc/core/core.h  |    1 +
 drivers/mmc/core/mmc.c   |   45 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mmc/card.h |    1 +
 include/linux/mmc/host.h |    5 +++++
 include/linux/mmc/mmc.h  |    1 +
 6 files changed, 80 insertions(+), 0 deletions(-)
drivers/mmc/core/core.c +27 -0
index 8f86d70..0c8882e 100644
@@ -209,6 +209,8 @@ static void mmc_wait_done(struct mmc_request *mrq)
  */
 void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
 {
+	struct mmc_card *card = host->card;
+
 	DECLARE_COMPLETION_ONSTACK(complete);
 
 	mrq->done_data = &complete;
@@ -217,6 +219,31 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
 	mmc_start_request(host, mrq);
 
 	wait_for_completion(&complete);
+
+	/* as MMC4.4 standard says, when some data timeout conditions
+	 * occur, HC need to do a hardware reset for eMMC4.4 card.
+	 * If the card is eMMC4.4 card && data error is timeout,
+	 * do the following things:
+	 * 1. let host controller do a specific hardware reset for eMMC
+	 *    card (trigger RST_n signal).
+	 * 2. after reset done, reinit eMMC4.4 card.
+	 * */
+	if (mrq->data && card &&
+		mrq->data->error == -ETIMEDOUT &&
+		card->ext_csd.rst == 1) {
+		int err = 1;
+		if (host->ops->hardware_reset &&
+				host->bus_ops->reinit) {
+			err = host->ops->hardware_reset(host);
+			if (err)
+				pr_warn("MMC card reset failed, no reinit\n");
+			else
+				err = host->bus_ops->reinit(host);
+		}
+
+		if (err)
+			pr_warn("cannot reset and reinit eMMC4.4 card\n");
+	}
 }
 
 EXPORT_SYMBOL(mmc_wait_for_req);
drivers/mmc/core/core.h +1 -0
index 77240cd..232a3d9 100644
@@ -24,6 +24,7 @@ struct mmc_bus_ops {
 	int (*resume)(struct mmc_host *);
 	int (*power_save)(struct mmc_host *);
 	int (*power_restore)(struct mmc_host *);
+	int (*reinit)(struct mmc_host *);
 };
 
 void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
drivers/mmc/core/mmc.c +45 -0

75 lines not on this page · raw message

include/linux/mmc/card.h +1 -0
index 8ce0827..ebee676 100644
@@ -54,6 +54,7 @@ struct mmc_ext_csd {
 	unsigned int		sec_trim_mult;	/* Secure trim multiplier  */
 	unsigned int		sec_erase_mult;	/* Secure erase multiplier */
 	unsigned int		trim_timeout;		/* In milliseconds */
+	unsigned int		rst; /* hardware reset enable bit */
 };
 
 struct sd_scr {
include/linux/mmc/host.h +5 -0
index 6d87f68..6e9eba8 100644
@@ -117,6 +117,11 @@ struct mmc_host_ops {
 
 	/* optional callback for HC quirks */
 	void	(*init_card)(struct mmc_host *host, struct mmc_card *card);
+
+	/* HW reset callback, used for eMMC 4.4 new feature.
+	 * when occurs data timeout, HC will need to reset eMMC4.4 card
+	 * */
+	int (*hardware_reset)(struct mmc_host *host);
 };
 
 struct mmc_card;
include/linux/mmc/mmc.h +1 -0
index 956fbd8..b7ab0da 100644
@@ -251,6 +251,7 @@ struct _mmc_csd {
  * EXT_CSD fields
  */
 
+#define EXT_CSD_RST		162	/* onetime programmable R/W */
 #define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
 #define EXT_CSD_ERASED_MEM_CONT		181	/* RO */
 #define EXT_CSD_BUS_WIDTH		183	/* R/W */
Signature · 1 line
1.6.6.1