Skip to contentSkip to conversation

mmc: To implement eMMC4.4 standard HW reset feature

RFC PATCH Superseded Chuanxiao.Dong 1 participant 1 message Aug 31, 2010

Subsystems (2)

v1 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 mmc: To implement eMMC4.4 standard HW reset feature

Hi all,
This is a RFC patch to implement eMMC4.4 standared HW reset feature. This patch is generated against the latest linus kernel git tree. I am not sure whether it is an appropriate source code tree for me to use, if anybody knows which tree is the appropritate one to generate linux-mmc patches, please let me know. Thanks very much :)

In this patch, only the framework is done. Actual reset and reinitialize operations will be done after this.

My understanding about HW reset feature:
1) To implement this, RST_n_FUNCTION field in extended CSD must be set to 1 to enable this feature.
2) when eMMC card occurs data timeout error, HC need to trigger a RST_n signal to reset eMMC card.
3) After HW reset, HC need to reinitialize eMMC card.
2) and 3) maybe need sleep or some delay.

Expect any feedback. Thank you all.

Quoted 1 line

From 6b7aaa0bfdb779678905246b1651d15cd93fd4d4 Mon Sep 17 00:00:00 2001

From: Chuanxiao Dong <[email protected]>
Date: Tue, 31 Aug 2010 16:45:02 +0800
Subject: [PATCH] linux-mmc: rfc patch: implement eMMC4.4 standard HW reset feature

This is a RFC patch which only has a framework. Detailed HW reset work and reinit work will be done later.

---
 drivers/mmc/core/core.c      |   27 +++++++++++++++++++++++
 drivers/mmc/core/core.h      |    1 +
 drivers/mmc/core/mmc.c       |   48 ++++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci-pci.c |   15 +++++++++++++
 drivers/mmc/host/sdhci.c     |   23 ++++++++++++++++++++
 drivers/mmc/host/sdhci.h     |    1 +
 include/linux/mmc/card.h     |    1 +
 include/linux/mmc/host.h     |    5 ++++
 include/linux/mmc/mmc.h      |    1 +
 9 files changed, 122 insertions(+), 0 deletions(-)
drivers/mmc/core/core.c +27 -0
index 5db49b1..dcf74d9 100644
@@ -208,6 +208,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;
@@ -216,6 +218,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 9d9eef5..d37e5e8 100644
@@ -24,6 +24,7 @@ struct mmc_bus_ops {
 	int (*resume)(struct mmc_host *);
 	void (*power_save)(struct mmc_host *);
 	void (*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 +48 -0

78 lines not on this page · raw message

drivers/mmc/host/sdhci-pci.c +15 -0
index e8aa99d..45afb93 100644
@@ -534,8 +534,23 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
 	return 0;
 }
 
+/*
+ * HW reset eMMC4.4 card callback
+ * In this function, driver need to trigger RST_n signal
+ * as eMMC4.4 standar says.
+ * RETURN VALUE:
+ * 0: reset emmc successfully
+ * 1: reset emmc failed
+ */
+static int sdhci_pci_reset_emmc(struct sdhci_host *host)
+{
+	/* TODO trigger a RST_n signal*/
+	return 0;
+}
+
 static struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
+	.reset_emmc = sdhci_pci_reset_emmc,
 };
 
 /*****************************************************************************\
drivers/mmc/host/sdhci.c +23 -0
index 401527d..1b15651 100644
@@ -1245,11 +1245,34 @@ out:
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
+/*
+ *  HW reset callback for eMMC4.4 card
+ *  In this function, HC will do the real HW reset
+ *  for eMMC4.4 card
+ *
+ *  RETURN VALUE:
+ *  0: reset emmc successfully
+ *  1: reset emmc failed
+ * */
+static int sdhci_hardware_reset(struct mmc_host *mmc)
+{
+	int err = 1;
+	struct sdhci_host *host;
+
+	host = mmc_priv(mmc);
+
+	if (host->ops && host->ops->reset_emmc)
+		err = host->ops->reset_emmc(host);
+
+	return err;
+}
+
 static const struct mmc_host_ops sdhci_ops = {
 	.request	= sdhci_request,
 	.set_ios	= sdhci_set_ios,
 	.get_ro		= sdhci_get_ro,
 	.enable_sdio_irq = sdhci_enable_sdio_irq,
+	.hardware_reset = sdhci_hardware_reset,
 };
 
 /*****************************************************************************\
drivers/mmc/host/sdhci.h +1 -0
index d316bc7..c9011b6 100644
@@ -323,6 +323,7 @@ struct sdhci_ops {
 	unsigned int	(*get_max_clock)(struct sdhci_host *host);
 	unsigned int	(*get_min_clock)(struct sdhci_host *host);
 	unsigned int	(*get_timeout_clock)(struct sdhci_host *host);
+	int		(*reset_emmc)(struct sdhci_host *host);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
include/linux/mmc/card.h +1 -0
index 6b75250..bf52b4b 100644
@@ -53,6 +53,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 char		rst;			/* identify HW reset cap */
 };
 
 struct sd_scr {
include/linux/mmc/host.h +5 -0
index 1575b52..6eefa34 100644
@@ -111,6 +111,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 dd11ae5..94c1a85 100644
@@ -251,6 +251,7 @@ struct _mmc_csd {
  * EXT_CSD fields
  */
 
+#define EXT_CSD_RST		162	/* 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