mmc: implemented eMMC4.4 hardware reset feature
PATCH 1/1 mmc: implemented eMMC4.4 hardware reset feature
Hi,
This patch implemented eMMC4.4 hardware reset feature in core layer and sdhci host layer, but need each sdhci host controller to implement the real reset part specially.
I also have a concern about the enabling hardware reset part. As eMMC 4.4 standar says, to enable hardware reset need to set the bit 0 of byte 162 in ext_csd register. However this register is onetime programmable, once setted, cannot be changed any more. And the standar also says this feature is disabled by default. If driver does not set it, the feature can not be enabled. So my question is that is it suitable for driver to set this bit?
Quoted 1 line
From
e14942d9c8fd6f0a77ca41b0f06381ec0a2abadeMon Sep 17 00:00:00 2001
From: Chuanxiao Dong <[email protected]>
Date: Mon, 25 Oct 2010 21:51:39 +0800
Subject: [PATCH] mmc: implemented eMMC 4.4 hardware reset feature
This feature is implemented in core layer and sdhci host layer. Each SDHCI host controller driver needs to implement the really reset eMMC card part specially.
In this patch, driver can detect whether eMMC card complies with 4.4 standar. If so, driver enable hardware reset feature for eMMC card.
When driver detect there occureed data timeout errors, driver will reset and then reinit eMMC card
--- drivers/mmc/core/core.c | 26 +++++++++++++++++++++++++ drivers/mmc/core/core.h | 1 + drivers/mmc/core/mmc.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 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 + 8 files changed, 105 insertions(+), 0 deletions(-)
drivers/mmc/core/core.c +26 -0
@@ -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,30 @@ 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
@@ -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 +47 -0
77 lines not on this page · raw message
drivers/mmc/host/sdhci.c +23 -0
@@ -1266,11 +1266,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
@@ -215,6 +215,7 @@ struct sdhci_ops {void (*platform_send_init_74_clocks)(struct sdhci_host *host,u8 power_mode);unsigned int (*get_ro)(struct sdhci_host *host); +int (*reset_emmc)(struct sdhci_host *host); };#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
include/linux/mmc/card.h +1 -0
@@ -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; };struct sd_scr {
include/linux/mmc/host.h +5 -0
@@ -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
@@ -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