All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/12] add support for host controller v3.00
@ 2011-04-15 10:38 Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23 Arindam Nath
                   ` (7 more replies)
  0 siblings, 8 replies; 27+ messages in thread
From: Arindam Nath @ 2011-04-15 10:38 UTC (permalink / raw)
  To: cjb
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd, Arindam Nath

V3
----
[01/12]: Changed function name from *_auto_cmd23_supported() to
         *_auto_cmd23_required().
[02/12]: Set bit 24 and bit 28 of OCR within mmc_sd_get_cid(),
         and only retry sending ACMD41 with bit 24 reset in case
         signal voltage switch procedure fails.
[02/12]: Change (*rocr & 0x41000000) to ((*rocr & 0x41000000) ==
         0x41000000) to check for both CCS and S18A to be set in
         the response of ACMD41.
[02/12]: Change the condition if (err == -EAGAIN) to if (err), in
         order to retry sending ACMD41 because of any error during
         signal voltage switch procedure.
[02/12]: Add a new variable signal_voltage to struct mmc_ios,
         which holds whether the request is to change to 1.8V or
         3.3V signalling voltage.
[03/12]: Remove redundant code to find bus speed modes for SD2.0
         and SD3.0 cards separately.
[03/12]: Change the variable names from uhs_* to sd3_* to make
         them appropriate to the context of their usage.
[04/12]: Change variable names from *_set_drv_type to *_drv_type.
[04/12]: Set driver type even when the default driver type B is
         used.
[04/12]: Clear bits 05-04 of Host Control 2 register before
         setting the new driver strength.
[05/12]: Use sdhci_set_clock() to make sure the clock is stable
         before re-enabling SD clock.
[06/12]: Initialize bus_speed and timing to 0 at the beginning of
         sd_set_bus_speed_mode() to avoid compiler warning.
[07/12]: Initialize current_limit to 0 to avoid compiler warning.
[07/12]: Remove usage of get_max_current_180() and replace this
         with MMC_CAP_MAX_CURRENT_*.
[07/12]: Set the current limit even for the default current limit
         of 200mA.
[07/12]: Set the current limit only for SDR50, SDR104, and DDR50
         UHS-I modes, otherwise set the default current limit.
[08/12]: Change mmc_*_ultrahighspeed() to mmc_sd_*_uhs().
[09/12]: Re-read Host Control 2 register before clearing
         *_TUNED_CLK and *_EXEC_TUNING.
[09/12]: Make sdhci_execute_tuning() return 'int' rather than
         'void' so that we can check for error conditions during
         tuning failure.
[09/12]: Make sure to return 0 for controllers which provide
         support for retuning even if tuning fails. For other
         controllers, return error code.
[10/12]: Disable using Preset Value when a new card is inserted,
         and enable its use only after a successfull UHS-I
         initializaton.
[12/12]: Remove sdhci_start_retuning_timer() completely, and start
         the re-tuning timer from within sdhci_execute_tuning()
         the very first time it is executed.

V2
----
[01/12]: Make saved_abort_cmd part of struct sdhci_host rather
         than global variable.
[01/12]: Clear SDHCI_USE_SDMA _iff_ SDHCI_USE_ADMA is set.
[01/12]: Set either Auto CMD23 or Auto CMD12, but not both, in
         the Transfer Mode register.
[02/12]: Check host controller version before reading
         SDHCI_CAPABILITIES_1.
[02/12]: Remove spinlock from sdhci_start_signal_voltage_switch
         and use usleep_range() rather than mdelay().
[02/12]: Set S18R in OCR to 1 for all UHS-I modes.
[02/12]: NULL pointer check for start_signal_voltage_switch().
[02/12]: Set MMC_CAP_UHS_SDR50 if MMC_CAP_UHS_SDR104 is set.
[06/12]: Add checking for SDR25 in sd_set_bus_speed_mode().
[09/12]: Remove checking for MMC_SEND_TUNING_BLOCK within
         sdhci_set_transfer_mode(), since cmd.data is set to
         NULL inside sdhci_execute_tuning().
[11/12]: Correctly set clk to SDHCI_PROG_CLOCK_MODE when host
         controller supports Programmable Clock Mode.

V1
----
The patches below add support for Host Controller v3.00 as per the
spec v3.00. It also adds support for UHS-I cards as per Physical
Layer Specification v3.01.

Thanks for review.

Regards,
Arindam

Arindam Nath (12):
  [PATCH 01/12] mmc: sdhci: add support for auto CMD23
  [PATCH 02/12] mmc: sd: add support for signal voltage switch procedure
  [PATCH 03/12] mmc: sd: query function modes for uhs cards
  [PATCH 04/12] mmc: sd: add support for driver type selection
  [PATCH 05/12] mmc: sdhci: reset sdclk before setting high speed enable
  [PATCH 06/12] mmc: sd: add support for uhs bus speed mode selection
  [PATCH 07/12] mmc: sd: set current limit for uhs cards
  [PATCH 08/12] mmc: sd: report correct speed and capacity of uhs cards
  [PATCH 09/12] mmc: sd: add support for tuning during uhs initialization
  [PATCH 10/12] mmc: sdhci: enable preset value after uhs initialization
  [PATCH 11/12] mmc: sdhci: add support for programmable clock mode
  [PATCH 12/12] mmc: sdhci: add support for retuning mode 1

 drivers/mmc/core/bus.c    |   11 +-
 drivers/mmc/core/core.c   |    9 +
 drivers/mmc/core/core.h   |    1 +
 drivers/mmc/core/sd.c     |  408 ++++++++++++++++++++++--
 drivers/mmc/core/sd.h     |    3 +-
 drivers/mmc/core/sd_ops.c |   34 ++
 drivers/mmc/core/sd_ops.h |    1 +
 drivers/mmc/core/sdio.c   |    3 +-
 drivers/mmc/host/sdhci.c  |  755 ++++++++++++++++++++++++++++++++++++++++++---
 drivers/mmc/host/sdhci.h  |   47 +++-
 include/linux/mmc/card.h  |   46 +++
 include/linux/mmc/host.h  |   36 +++
 include/linux/mmc/mmc.h   |    1 +
 include/linux/mmc/sd.h    |    3 +-
 include/linux/mmc/sdhci.h |   13 +
 15 files changed, 1283 insertions(+), 88 deletions(-)


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

* [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
@ 2011-04-15 10:38 ` Arindam Nath
       [not found]   ` <BANLkTimZGonC+D0czjiY4i7pFFW=upj_qw@mail.gmail.com>
  2011-04-15 10:38 ` [PATCH v3 02/12] mmc: sd: add support for signal voltage switch procedure Arindam Nath
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 27+ messages in thread
From: Arindam Nath @ 2011-04-15 10:38 UTC (permalink / raw)
  To: cjb
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd, Arindam Nath

Host Controller v3.00 and later support Auto CMD23 in the Transfer
Mode register. Since Auto CMD23 can be used with or without DMA,
and if used with DMA, it should _only_ be ADMA, we check against
SDHCI_USE_SDMA not being set. This flag is reset when SDHCI_USE_ADMA
is set.

A new definition for SDHCI_ARGUMENT2 register has been added in v3.00
spec, which is the same as SDHCI_DMA_ADDRESS. We program the block
count for CMD23 in SDHCI_ARGUMENT2, so we don't need CMD12 to stop
multiple block transfers. But during error recovery procedure, we will
need to send Abort command, so we use a variable saved_abort_cmd to
save the stop command to be used later.

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
---
 drivers/mmc/core/sd.c     |    6 ++++
 drivers/mmc/host/sdhci.c  |   71 +++++++++++++++++++++++++++++++++++++++++---
 drivers/mmc/host/sdhci.h  |    2 +
 include/linux/mmc/card.h  |    4 ++
 include/linux/mmc/sd.h    |    2 +-
 include/linux/mmc/sdhci.h |    2 +
 6 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 6dac89f..460ec24 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -189,6 +189,12 @@ static int mmc_decode_scr(struct mmc_card *card)
 
 	scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
 	scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
+	if (scr->sda_vsn == SCR_SPEC_VER_2) {
+		/* Check if Physical Layer Spec v3.0 is supported*/
+		scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
+		if (scr->sda_spec3)
+			scr->cmd_support = UNSTUFF_BITS(resp, 32, 2);
+	}
 
 	if (UNSTUFF_BITS(resp, 55, 1))
 		card->erased_byte = 0xFF;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 94793f2..7921ced 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -25,6 +25,7 @@
 
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
 
 #include "sdhci.h"
 
@@ -821,6 +822,30 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
 	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
 }
 
+/*
+ * Does the Host Controller support Auto CMD23?
+ *
+ * There are four preconditions for Auto CMD23 to be supported:
+ *  1. Host Controller v3.00 or later
+ *  2. Card supports CMD23
+ *  3. If DMA is used, it should be ADMA
+ *  4. Only when CMD18 or CMD25 is issued
+ */
+static int sdhci_host_auto_cmd23_required(struct sdhci_host *host,
+	struct mmc_request *mrq)
+{
+	struct mmc_card *card = host->mmc->card;
+
+	if ((host->version >= SDHCI_SPEC_300) &&
+	   card && (card->scr.cmd_support & SD_SCR_CMD23_SUPPORT) &&
+	   !(host->flags & SDHCI_USE_SDMA) &&
+	   ((mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK) ||
+	   (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK)))
+		return 1;
+
+	return 0;
+}
+
 static void sdhci_set_transfer_mode(struct sdhci_host *host,
 	struct mmc_data *data)
 {
@@ -834,10 +859,21 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
 	mode = SDHCI_TRNS_BLK_CNT_EN;
 	if (data->blocks > 1) {
 		if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
-			mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
-		else
-			mode |= SDHCI_TRNS_MULTI;
+			mode |= SDHCI_TRNS_ACMD12;
+		else if (sdhci_host_auto_cmd23_required(host, host->mrq)) {
+			/*
+			 * Host Controller v3.00 can automatically send CMD23
+			 * before CMD18 or CMD25. For that, we need to enable
+			 * Auto CMD23 in the Transfer Mode register and
+			 * program the block count in Argument 2 register.
+			 */
+			mode |= SDHCI_TRNS_AUTO_CMD23;
+			sdhci_writel(host, data->blocks, SDHCI_ARGUMENT2);
+		}
+
+		mode |= SDHCI_TRNS_MULTI;
 	}
+
 	if (data->flags & MMC_DATA_READ)
 		mode |= SDHCI_TRNS_READ;
 	if (host->flags & SDHCI_REQ_USE_DMA)
@@ -1140,6 +1176,23 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 #ifndef SDHCI_USE_LEDS_CLASS
 	sdhci_activate_led(host);
 #endif
+	/*
+	 * Since the block count for CMD23 has already been specified in the
+	 * Argument 2 register, we don't need CMD12 to stop multiple block
+	 * transfers.
+	 */
+	if (sdhci_host_auto_cmd23_required(host, mrq)) {
+		if (mrq->stop) {
+			/*
+			 * Save the stop command here to be used during
+			 * error recovery
+			 */
+			host->saved_abort_cmd = mrq->data->stop;
+			mrq->data->stop = NULL;
+			mrq->stop = NULL;
+		}
+	}
+
 	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) {
 		if (mrq->stop) {
 			mrq->data->stop = NULL;
@@ -1405,6 +1458,8 @@ static void sdhci_timeout_timer(unsigned long data)
 
 		if (host->data) {
 			host->data->error = -ETIMEDOUT;
+			if (host->saved_abort_cmd)
+				host->data->stop = host->saved_abort_cmd;
 			sdhci_finish_data(host);
 		} else {
 			if (host->cmd)
@@ -1543,9 +1598,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
 		host->data->error = -EIO;
 	}
 
-	if (host->data->error)
+	if (host->data->error) {
+		if (host->saved_abort_cmd)
+			host->data->stop = host->saved_abort_cmd;
 		sdhci_finish_data(host);
-	else {
+	} else {
 		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
 			sdhci_transfer_pio(host);
 
@@ -1819,6 +1876,10 @@ int sdhci_add_host(struct sdhci_host *host)
 		host->flags &= ~SDHCI_USE_ADMA;
 	}
 
+	/* If the host can perform ADMA operation, we reset SDMA flag */
+	if (host->flags & SDHCI_USE_ADMA)
+		host->flags &= ~SDHCI_USE_SDMA;
+
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
 		if (host->ops->enable_dma) {
 			if (host->ops->enable_dma(host)) {
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 85750a9..9f8575e 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -25,6 +25,7 @@
  */
 
 #define SDHCI_DMA_ADDRESS	0x00
+#define SDHCI_ARGUMENT2		SDHCI_DMA_ADDRESS
 
 #define SDHCI_BLOCK_SIZE	0x04
 #define  SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
@@ -37,6 +38,7 @@
 #define  SDHCI_TRNS_DMA		0x01
 #define  SDHCI_TRNS_BLK_CNT_EN	0x02
 #define  SDHCI_TRNS_ACMD12	0x04
+#define  SDHCI_TRNS_AUTO_CMD23	0x08
 #define  SDHCI_TRNS_READ	0x10
 #define  SDHCI_TRNS_MULTI	0x20
 
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 72a9868..86d9672 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -67,9 +67,13 @@ struct mmc_ext_csd {
 
 struct sd_scr {
 	unsigned char		sda_vsn;
+	unsigned char		sda_spec3;
 	unsigned char		bus_widths;
 #define SD_SCR_BUS_WIDTH_1	(1<<0)
 #define SD_SCR_BUS_WIDTH_4	(1<<2)
+	unsigned char		cmd_support;
+#define SD_SCR_CMD20_SUPPORT	(1<<0)
+#define SD_SCR_CMD23_SUPPORT	(1<<1)
 };
 
 struct sd_ssr {
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
index 3fd85e0..178363b 100644
--- a/include/linux/mmc/sd.h
+++ b/include/linux/mmc/sd.h
@@ -59,7 +59,7 @@
 
 #define SCR_SPEC_VER_0		0	/* Implements system specification 1.0 - 1.01 */
 #define SCR_SPEC_VER_1		1	/* Implements system specification 1.10 */
-#define SCR_SPEC_VER_2		2	/* Implements system specification 2.00 */
+#define SCR_SPEC_VER_2		2	/* Implements system specification 2.00 - 3.0x */
 
 /*
  * SD bus widths
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 83bd9f7..282d158 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -145,6 +145,8 @@ struct sdhci_host {
 	unsigned int            ocr_avail_sd;
 	unsigned int            ocr_avail_mmc;
 
+	struct mmc_command	*saved_abort_cmd; /* Abort command saved for data error recovery */
+
 	unsigned long private[0] ____cacheline_aligned;
 };
 #endif /* __SDHCI_H */
-- 
1.7.1


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

* [PATCH v3 02/12] mmc: sd: add support for signal voltage switch procedure
  2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23 Arindam Nath
@ 2011-04-15 10:38 ` Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 03/12] mmc: sd: query function modes for uhs cards Arindam Nath
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Arindam Nath @ 2011-04-15 10:38 UTC (permalink / raw)
  To: cjb
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd, Arindam Nath

Host Controller v3.00 adds another Capabilities register. Apart
from other things, this new register indicates whether the Host
Controller supports SDR50, SDR104, and DDR50 UHS-I modes. The spec
doesn't mention about explicit support for SDR12 and SDR25 UHS-I
modes, so the Host Controller v3.00 should support them by default.
Also if the controller supports SDR104 mode, it will also support
SDR50 mode as well. So depending on the host support, we set the
corresponding MMC_CAP_* flags. One more new register. Host Control2
is added in v3.00, which is used during Signal Voltage Switch
procedure described below.

Since as per v3.00 spec, UHS-I supported hosts should set S18R
to 1, we set S18R (bit 24) of OCR before sending ACMD41. We also
need to set XPC (bit 28) of OCR in case the host can supply >150mA.
This support is indicated by the Maximum Current Capabilities
register of the Host Controller.

If the response of ACMD41 has both CCS and S18A set, we start the
signal voltage switch procedure, which if successfull, will switch
the card from 3.3V signalling to 1.8V signalling. Signal voltage
switch procedure adds support for a new command CMD11 in the
Physical Layer Spec v3.01. As part of this procedure, we need to
set 1.8V Signalling Enable (bit 3) of Host Control2 register, which
if remains set after 5ms, means the switch to 1.8V signalling is
successfull. Otherwise, we clear bit 24 of OCR and retry the
initialization sequence. When we remove the card, and insert the
same or another card, we need to make sure that we start with 3.3V
signalling voltage. So we call mmc_set_signal_voltage() with
MMC_SIGNAL_VOLTAGE_330 set so that we are back to 3.3V signalling
voltage before we actually start initializing the card.

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
---
 drivers/mmc/core/sd.c     |   34 ++++++++-
 drivers/mmc/core/sd_ops.c |   34 ++++++++
 drivers/mmc/core/sd_ops.h |    1 +
 drivers/mmc/host/sdhci.c  |  189 +++++++++++++++++++++++++++++++++++++++++---
 drivers/mmc/host/sdhci.h  |   18 ++++-
 include/linux/mmc/host.h  |   15 ++++
 include/linux/mmc/sd.h    |    1 +
 7 files changed, 276 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 460ec24..b967588 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -409,6 +409,7 @@ struct device_type sd_type = {
 int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
 {
 	int err;
+	u32 rocr;
 
 	/*
 	 * Since we're changing the OCR value, we seem to
@@ -428,10 +429,36 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
 	if (!err)
 		ocr |= 1 << 30;
 
-	err = mmc_send_app_op_cond(host, ocr, NULL);
+	/*
+	 * If the host supports one of UHS-I modes, request the card
+	 * to switch to 1.8V signaling level.
+	 */
+	if (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))
+		ocr |= 1 << 24;
+
+	/* If the host can supply more than 150mA, XPC should be set to 1. */
+	if (host->caps & (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 |
+	    MMC_CAP_SET_XPC_180))
+		ocr |= 1 << 28;
+
+try_again:
+	err = mmc_send_app_op_cond(host, ocr, &rocr);
 	if (err)
 		return err;
 
+	/*
+	 * In case CCS and S18A in the response is set, start Signal Voltage
+	 * Switch procedure. SPI mode doesn't support CMD11.
+	 */
+	if (!mmc_host_is_spi(host) && ((rocr & 0x41000000) == 0x41000000)) {
+		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
+		if (err) {
+			ocr &= ~(1 << 24);
+			goto try_again;
+		}
+	}
+
 	if (mmc_host_is_spi(host))
 		err = mmc_send_cid(host, cid);
 	else
@@ -787,6 +814,11 @@ int mmc_attach_sd(struct mmc_host *host)
 	if (host->ocr_avail_sd)
 		host->ocr_avail = host->ocr_avail_sd;
 
+	/* Make sure we are at 3.3V signalling voltage */
+	err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330);
+	if (err)
+		return err;
+
 	/*
 	 * We need to get OCR a different way for SPI.
 	 */
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index da50849..fc7edc4 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -149,6 +149,40 @@ int mmc_app_set_bus_width(struct mmc_card *card, int width)
 	return 0;
 }
 
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
+{
+	struct mmc_command cmd;
+	int err = 0;
+
+	BUG_ON(!host);
+
+	/*
+	 * Send CMD11 only if the request is to switch the card to
+	 * 1.8V signalling.
+	 */
+	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+		memset(&cmd, 0, sizeof(struct mmc_command));
+
+		cmd.opcode = SD_SWITCH_VOLTAGE;
+		cmd.arg = 0;
+		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+		err = mmc_wait_for_cmd(host, &cmd, 0);
+		if (err)
+			return err;
+
+		if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
+			return -EIO;
+	}
+
+	host->ios.signal_voltage = signal_voltage;
+
+	if (host->ops->start_signal_voltage_switch)
+		err = host->ops->start_signal_voltage_switch(host, &host->ios);
+
+	return err;
+}
+
 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 {
 	struct mmc_command cmd;
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h
index ffc2305..d5bdda5 100644
--- a/drivers/mmc/core/sd_ops.h
+++ b/drivers/mmc/core/sd_ops.h
@@ -20,6 +20,7 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr);
 int mmc_sd_switch(struct mmc_card *card, int mode, int group,
 	u8 value, u8 *resp);
 int mmc_app_sd_status(struct mmc_card *card, void *ssr);
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
 
 #endif
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 7921ced..86db5e5 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -84,6 +84,8 @@ static void sdhci_dumpregs(struct sdhci_host *host)
 	printk(KERN_DEBUG DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
 		sdhci_readw(host, SDHCI_COMMAND),
 		sdhci_readl(host, SDHCI_MAX_CURRENT));
+	printk(KERN_DEBUG DRIVER_NAME ": Host ctl2: 0x%08x\n",
+		sdhci_readw(host, SDHCI_HOST_CONTROL2));
 
 	if (host->flags & SDHCI_USE_ADMA)
 		printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
@@ -1346,11 +1348,111 @@ out:
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
+	struct mmc_ios *ios)
+{
+	struct sdhci_host *host;
+	u8 pwr;
+	u16 clk, ctrl;
+	u32 present_state;
+
+	host = mmc_priv(mmc);
+
+	/*
+	 * Signal Voltage Switching is only applicable for Host Controllers
+	 * v3.00 and above.
+	 */
+	if (host->version < SDHCI_SPEC_300)
+		return 0;
+
+	/*
+	 * We first check whether the request is to set signalling voltage
+	 * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
+	 */
+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+	if ((ctrl & SDHCI_CTRL_VDD_180) &&
+	   (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)) {
+		/* Set 1.8V Signal Enable in the Host Control2 register to 0 */
+		ctrl &= ~SDHCI_CTRL_VDD_180;
+		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+
+		/* Wait for 5ms */
+		usleep_range(5000, 5500);
+
+		/* 3.3V regulator output should be stable within 5 ms */
+		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+		if (!(ctrl & SDHCI_CTRL_VDD_180))
+			return 0;
+		else {
+			printk(KERN_INFO DRIVER_NAME ": Switching to 3.3V "
+				"signalling voltage failed\n");
+			return -EIO;
+		}
+	} else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
+		  (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) {
+		/* Stop SDCLK */
+		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+		clk &= ~SDHCI_CLOCK_CARD_EN;
+		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+		/* Check whether DAT[3:0] is 0000 */
+		present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
+		if (!((present_state & SDHCI_DATA_LVL_MASK) >>
+		       SDHCI_DATA_LVL_SHIFT)) {
+			/*
+			 * Enable 1.8V Signal Enable in the Host Control2
+			 * register
+			 */
+			ctrl |= SDHCI_CTRL_VDD_180;
+			sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+
+			/* Wait for 5ms */
+			usleep_range(5000, 5500);
+
+			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+			if (ctrl & SDHCI_CTRL_VDD_180) {
+				/* Provide SDCLK again and wait for 1ms*/
+				clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+				clk |= SDHCI_CLOCK_CARD_EN;
+				sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+				usleep_range(1000, 1500);
+
+				/*
+				 * If DAT[3:0] level is 1111b, then the card
+				 * was successfully switched to 1.8V signaling.
+				 */
+				present_state = sdhci_readl(host,
+							SDHCI_PRESENT_STATE);
+				if ((present_state & SDHCI_DATA_LVL_MASK) ==
+				     SDHCI_DATA_LVL_MASK) {
+					return 0;
+				}
+			}
+		}
+
+		/*
+		 * If we are here, that means the switch to 1.8V signaling
+		 * failed. Stop power to the card, and retry initialization
+		 * sequence by setting S18R to 0.
+		 */
+		pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
+		pwr &= ~SDHCI_POWER_ON;
+		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+
+		printk(KERN_INFO DRIVER_NAME ": Switching to 1.8V signalling "
+			"voltage failed, retrying with S18R set to 0\n");
+		return -EAGAIN;
+	} else
+		/* No signal voltage switch required */
+		return 0;
+}
+
 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,
+	.start_signal_voltage_switch	= sdhci_start_signal_voltage_switch,
 };
 
 /*****************************************************************************\
@@ -1828,7 +1930,9 @@ EXPORT_SYMBOL_GPL(sdhci_alloc_host);
 int sdhci_add_host(struct sdhci_host *host)
 {
 	struct mmc_host *mmc;
-	unsigned int caps, ocr_avail;
+	u32 caps[2];
+	u32 max_current_caps;
+	unsigned int ocr_avail;
 	int ret;
 
 	WARN_ON(host == NULL);
@@ -1851,12 +1955,15 @@ int sdhci_add_host(struct sdhci_host *host)
 			host->version);
 	}
 
-	caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
+	caps[0] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
 		sdhci_readl(host, SDHCI_CAPABILITIES);
 
+	caps[1] = (host->version >= SDHCI_SPEC_300) ?
+		sdhci_readl(host, SDHCI_CAPABILITIES_1) : 0;
+
 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
 		host->flags |= SDHCI_USE_SDMA;
-	else if (!(caps & SDHCI_CAN_DO_SDMA))
+	else if (!(caps[0] & SDHCI_CAN_DO_SDMA))
 		DBG("Controller doesn't have SDMA capability\n");
 	else
 		host->flags |= SDHCI_USE_SDMA;
@@ -1867,7 +1974,8 @@ int sdhci_add_host(struct sdhci_host *host)
 		host->flags &= ~SDHCI_USE_SDMA;
 	}
 
-	if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
+	if ((host->version >= SDHCI_SPEC_200) &&
+		(caps[0] & SDHCI_CAN_DO_ADMA2))
 		host->flags |= SDHCI_USE_ADMA;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
@@ -1921,10 +2029,10 @@ int sdhci_add_host(struct sdhci_host *host)
 	}
 
 	if (host->version >= SDHCI_SPEC_300)
-		host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK)
+		host->max_clk = (caps[0] & SDHCI_CLOCK_V3_BASE_MASK)
 			>> SDHCI_CLOCK_BASE_SHIFT;
 	else
-		host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK)
+		host->max_clk = (caps[0] & SDHCI_CLOCK_BASE_MASK)
 			>> SDHCI_CLOCK_BASE_SHIFT;
 
 	host->max_clk *= 1000000;
@@ -1940,7 +2048,7 @@ int sdhci_add_host(struct sdhci_host *host)
 	}
 
 	host->timeout_clk =
-		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
+		(caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
 	if (host->timeout_clk == 0) {
 		if (host->ops->get_timeout_clock) {
 			host->timeout_clk = host->ops->get_timeout_clock(host);
@@ -1952,7 +2060,7 @@ int sdhci_add_host(struct sdhci_host *host)
 			return -ENODEV;
 		}
 	}
-	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
+	if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
 		host->timeout_clk *= 1000;
 
 	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
@@ -1982,21 +2090,76 @@ int sdhci_add_host(struct sdhci_host *host)
 	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
-	if (caps & SDHCI_CAN_DO_HISPD)
+	if (caps[0] & SDHCI_CAN_DO_HISPD)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) &&
 	    mmc_card_is_removable(mmc))
 		mmc->caps |= MMC_CAP_NEEDS_POLL;
 
+	/* UHS-I mode(s) supported by the host controller. */
+	if (host->version >= SDHCI_SPEC_300)
+		mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
+
+	/* SDR104 supports also implies SDR50 support */
+	if (caps[1] & SDHCI_SUPPORT_SDR104)
+		mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50;
+	else if (caps[1] & SDHCI_SUPPORT_SDR50)
+		mmc->caps |= MMC_CAP_UHS_SDR50;
+
+	if (caps[1] & SDHCI_SUPPORT_DDR50)
+		mmc->caps |= MMC_CAP_UHS_DDR50;
+
 	ocr_avail = 0;
-	if (caps & SDHCI_CAN_VDD_330)
+	/*
+	 * According to SD Host Controller spec v3.00, if the Host System
+	 * can afford more than 150mA, Host Driver should set XPC to 1. Also
+	 * the value is meaningful only if Voltage Support in the Capabilities
+	 * register is set. The actual current value is 4 times the register
+	 * value.
+	 */
+	max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT);
+
+	if (caps[0] & SDHCI_CAN_VDD_330) {
+		int max_current_330;
+
 		ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
-	if (caps & SDHCI_CAN_VDD_300)
+
+		max_current_330 = ((max_current_caps &
+				   SDHCI_MAX_CURRENT_330_MASK) >>
+				   SDHCI_MAX_CURRENT_330_SHIFT) *
+				   SDHCI_MAX_CURRENT_MULTIPLIER;
+
+		if (max_current_330 > 150)
+			mmc->caps |= MMC_CAP_SET_XPC_330;
+	}
+	if (caps[0] & SDHCI_CAN_VDD_300) {
+		int max_current_300;
+
 		ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31;
-	if (caps & SDHCI_CAN_VDD_180)
+
+		max_current_300 = ((max_current_caps &
+				   SDHCI_MAX_CURRENT_300_MASK) >>
+				   SDHCI_MAX_CURRENT_300_SHIFT) *
+				   SDHCI_MAX_CURRENT_MULTIPLIER;
+
+		if (max_current_300 > 150)
+			mmc->caps |= MMC_CAP_SET_XPC_300;
+	}
+	if (caps[0] & SDHCI_CAN_VDD_180) {
+		int max_current_180;
+
 		ocr_avail |= MMC_VDD_165_195;
 
+		max_current_180 = ((max_current_caps &
+				   SDHCI_MAX_CURRENT_180_MASK) >>
+				   SDHCI_MAX_CURRENT_180_SHIFT) *
+				   SDHCI_MAX_CURRENT_MULTIPLIER;
+
+		if (max_current_180 > 150)
+			mmc->caps |= MMC_CAP_SET_XPC_180;
+	}
+
 	mmc->ocr_avail = ocr_avail;
 	mmc->ocr_avail_sdio = ocr_avail;
 	if (host->ocr_avail_sdio)
@@ -2056,7 +2219,7 @@ int sdhci_add_host(struct sdhci_host *host)
 	if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
 		mmc->max_blk_size = 2;
 	} else {
-		mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
+		mmc->max_blk_size = (caps[0] & SDHCI_MAX_BLOCK_MASK) >>
 				SDHCI_MAX_BLOCK_SHIFT;
 		if (mmc->max_blk_size >= 3) {
 			printk(KERN_WARNING "%s: Invalid maximum block size, "
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 9f8575e..7b53e10 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -70,6 +70,8 @@
 #define  SDHCI_DATA_AVAILABLE	0x00000800
 #define  SDHCI_CARD_PRESENT	0x00010000
 #define  SDHCI_WRITE_PROTECT	0x00080000
+#define  SDHCI_DATA_LVL_MASK	0x00F00000
+#define   SDHCI_DATA_LVL_SHIFT	20
 
 #define SDHCI_HOST_CONTROL 	0x28
 #define  SDHCI_CTRL_LED		0x01
@@ -148,7 +150,8 @@
 
 #define SDHCI_ACMD12_ERR	0x3C
 
-/* 3E-3F reserved */
+#define SDHCI_HOST_CONTROL2		0x3E
+#define  SDHCI_CTRL_VDD_180		0x0008
 
 #define SDHCI_CAPABILITIES	0x40
 #define  SDHCI_TIMEOUT_CLK_MASK	0x0000003F
@@ -169,9 +172,20 @@
 #define  SDHCI_CAN_VDD_180	0x04000000
 #define  SDHCI_CAN_64BIT	0x10000000
 
+#define  SDHCI_SUPPORT_SDR50	0x00000001
+#define  SDHCI_SUPPORT_SDR104	0x00000002
+#define  SDHCI_SUPPORT_DDR50	0x00000004
+
 #define SDHCI_CAPABILITIES_1	0x44
 
-#define SDHCI_MAX_CURRENT	0x48
+#define SDHCI_MAX_CURRENT		0x48
+#define  SDHCI_MAX_CURRENT_330_MASK	0x0000FF
+#define  SDHCI_MAX_CURRENT_330_SHIFT	0
+#define  SDHCI_MAX_CURRENT_300_MASK	0x00FF00
+#define  SDHCI_MAX_CURRENT_300_SHIFT	8
+#define  SDHCI_MAX_CURRENT_180_MASK	0xFF0000
+#define  SDHCI_MAX_CURRENT_180_SHIFT	16
+#define   SDHCI_MAX_CURRENT_MULTIPLIER	4
 
 /* 4C-4F reserved for more max current */
 
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 4f705eb..e7f6e64 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -56,6 +56,11 @@ struct mmc_ios {
 #define MMC_SDR_MODE		0
 #define MMC_1_2V_DDR_MODE	1
 #define MMC_1_8V_DDR_MODE	2
+
+	unsigned char	signal_voltage;		/* signalling voltage (1.8V or 3.3V) */
+
+#define MMC_SIGNAL_VOLTAGE_330	0
+#define MMC_SIGNAL_VOLTAGE_180	1
 };
 
 struct mmc_host_ops {
@@ -117,6 +122,8 @@ struct mmc_host_ops {
 
 	/* optional callback for HC quirks */
 	void	(*init_card)(struct mmc_host *host, struct mmc_card *card);
+
+	int	(*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
 };
 
 struct mmc_card;
@@ -173,6 +180,14 @@ struct mmc_host {
 						/* DDR mode at 1.2V */
 #define MMC_CAP_POWER_OFF_CARD	(1 << 13)	/* Can power off after boot */
 #define MMC_CAP_BUS_WIDTH_TEST	(1 << 14)	/* CMD14/CMD19 bus width ok */
+#define MMC_CAP_UHS_SDR12	(1 << 15)	/* Host supports UHS SDR12 mode */
+#define MMC_CAP_UHS_SDR25	(1 << 16)	/* Host supports UHS SDR25 mode */
+#define MMC_CAP_UHS_SDR50	(1 << 17)	/* Host supports UHS SDR50 mode */
+#define MMC_CAP_UHS_SDR104	(1 << 18)	/* Host supports UHS SDR104 mode */
+#define MMC_CAP_UHS_DDR50	(1 << 19)	/* Host supports UHS DDR50 mode */
+#define MMC_CAP_SET_XPC_330	(1 << 20)	/* Host supports >150mA current at 3.3V */
+#define MMC_CAP_SET_XPC_300	(1 << 21)	/* Host supports >150mA current at 3.0V */
+#define MMC_CAP_SET_XPC_180	(1 << 22)	/* Host supports >150mA current at 1.8V */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
index 178363b..3ba5aa6 100644
--- a/include/linux/mmc/sd.h
+++ b/include/linux/mmc/sd.h
@@ -17,6 +17,7 @@
 /* This is basically the same command as for MMC with some quirks. */
 #define SD_SEND_RELATIVE_ADDR     3   /* bcr                     R6  */
 #define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7  */
+#define SD_SWITCH_VOLTAGE         11  /* ac                      R1  */
 
   /* class 10 */
 #define SD_SWITCH                 6   /* adtc [31:0] See below   R1  */
-- 
1.7.1


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

* [PATCH v3 03/12] mmc: sd: query function modes for uhs cards
  2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23 Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 02/12] mmc: sd: add support for signal voltage switch procedure Arindam Nath
@ 2011-04-15 10:38 ` Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 04/12] mmc: sd: add support for driver type selection Arindam Nath
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Arindam Nath @ 2011-04-15 10:38 UTC (permalink / raw)
  To: cjb
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd, Arindam Nath

SD cards which conform to Physical Layer Spec v3.01 can support
additional Bus Speed Modes, Driver Strength, and Current Limit
other than the default values. We use CMD6 mode 0 to read these
additional card functions. The values read here will be used
during UHS-I initialization steps.

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
---
 drivers/mmc/core/sd.c    |   66 ++++++++++++++++++++++++++++++++++++++++-----
 include/linux/mmc/card.h |    3 ++
 2 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index b967588..eefa4aa 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -284,25 +284,75 @@ static int mmc_read_switch(struct mmc_card *card)
 		return -ENOMEM;
 	}
 
+	/* Find out the supported Bus Speed Modes. */
 	err = mmc_sd_switch(card, 0, 0, 1, status);
 	if (err) {
-		/* If the host or the card can't do the switch,
-		 * fail more gracefully. */
+		/*
+		 * If the host or the card can't do the switch,
+		 * fail more gracefully.
+		 */
 		if ((err != -EINVAL)
-		 && (err != -ENOSYS)
-		 && (err != -EFAULT))
+		&& (err != -ENOSYS)
+		&& (err != -EFAULT))
 			goto out;
 
-		printk(KERN_WARNING "%s: problem reading switch "
-			"capabilities, performance might suffer.\n",
+		printk(KERN_WARNING "%s: problem reading Bus Speed modes.\n",
 			mmc_hostname(card->host));
 		err = 0;
 
 		goto out;
 	}
 
-	if (status[13] & 0x02)
-		card->sw_caps.hs_max_dtr = 50000000;
+	if (card->scr.sda_spec3) {
+		card->sw_caps.sd3_bus_mode = status[13];
+
+		/* Find out Driver Strengths supported by the card */
+		err = mmc_sd_switch(card, 0, 2, 1, status);
+		if (err) {
+			/*
+			 * If the host or the card can't do the switch,
+			 * fail more gracefully.
+			 */
+			if ((err != -EINVAL)
+			&& (err != -ENOSYS)
+			&& (err != -EFAULT))
+				goto out;
+
+			printk(KERN_WARNING "%s: problem reading "
+				"Driver Strength.\n",
+				mmc_hostname(card->host));
+			err = 0;
+
+			goto out;
+		}
+
+		card->sw_caps.sd3_drv_type = status[9];
+
+		/* Find out Current Limits supported by the card */
+		err = mmc_sd_switch(card, 0, 3, 1, status);
+		if (err) {
+			/*
+			 * If the host or the card can't do the switch,
+			 * fail more gracefully.
+			 */
+			if ((err != -EINVAL)
+			&& (err != -ENOSYS)
+			&& (err != -EFAULT))
+				goto out;
+
+			printk(KERN_WARNING "%s: problem reading "
+				"Current Limit.\n",
+				mmc_hostname(card->host));
+			err = 0;
+
+			goto out;
+		}
+
+		card->sw_caps.sd3_curr_limit = status[7];
+	} else {
+		if (status[13] & 0x02)
+			card->sw_caps.hs_max_dtr = 50000000;
+	}
 
 out:
 	kfree(status);
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 86d9672..18b0334 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -84,6 +84,9 @@ struct sd_ssr {
 
 struct sd_switch_caps {
 	unsigned int		hs_max_dtr;
+	unsigned int		sd3_bus_mode;
+	unsigned int		sd3_drv_type;
+	unsigned int		sd3_curr_limit;
 };
 
 struct sdio_cccr {
-- 
1.7.1


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

* [PATCH v3 04/12] mmc: sd: add support for driver type selection
  2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
                   ` (2 preceding siblings ...)
  2011-04-15 10:38 ` [PATCH v3 03/12] mmc: sd: query function modes for uhs cards Arindam Nath
@ 2011-04-15 10:38 ` Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 05/12] mmc: sdhci: reset sdclk before setting high speed enable Arindam Nath
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Arindam Nath @ 2011-04-15 10:38 UTC (permalink / raw)
  To: cjb
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd, Arindam Nath

This patch adds support for setting driver strength during UHS-I
initialization prcedure. Since UHS-I cards set S18A (bit 24) in
response to ACMD41, we use this as a base for UHS-I initialization.
We modify the parameter list of mmc_sd_get_cid() so that we can
save the ROCR from ACMD41 to check whether bit 24 is set.

We decide whether the Host Controller supports A, C, or D driver
type depending on the Capabilities register. Driver type B is
suported by default. We then set the appropriate driver type for
the card using CMD6 mode 1. As per Host Controller spec v3.00, we
set driver type for the host only if Preset Value Enable in the
Host Control2 register is not set. SDHCI_HOST_CONTROL has been
renamed to SDHCI_HOST_CONTROL1 to conform to the spec.

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
---
 drivers/mmc/core/core.c  |    9 +++
 drivers/mmc/core/core.h  |    1 +
 drivers/mmc/core/sd.c    |  153 ++++++++++++++++++++++++++++++++++++++--------
 drivers/mmc/core/sd.h    |    3 +-
 drivers/mmc/core/sdio.c  |    3 +-
 drivers/mmc/host/sdhci.c |   49 +++++++++++---
 drivers/mmc/host/sdhci.h |   11 +++-
 include/linux/mmc/card.h |    4 +
 include/linux/mmc/host.h |   10 +++
 9 files changed, 203 insertions(+), 40 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 5178d5d..91ab31f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -954,6 +954,15 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
 }
 
 /*
+ * Select appropriate driver type for host.
+ */
+void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
+{
+	host->ios.drv_type = drv_type;
+	mmc_set_ios(host);
+}
+
+/*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
  * We then wait a bit for the power to stabilise.  Finally,
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index ca1fdde..6114ca5 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -42,6 +42,7 @@ void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
 			   unsigned int ddr);
 u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
 void mmc_set_timing(struct mmc_host *host, unsigned int timing);
+void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
 
 static inline void mmc_delay(unsigned int ms)
 {
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index eefa4aa..dd0ae2c 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -408,6 +408,98 @@ out:
 	return err;
 }
 
+static int sd_select_driver_type(struct mmc_card *card, u8 *status)
+{
+	int host_drv_type = 0, card_drv_type = 0;
+	int err;
+
+	/*
+	 * If the host doesn't support any of the Driver Types A,C or D,
+	 * default Driver Type B is used.
+	 */
+	if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C
+	    | MMC_CAP_DRIVER_TYPE_D)))
+		return 0;
+
+	if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) {
+		host_drv_type = MMC_SET_DRIVER_TYPE_A;
+		if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A)
+			card_drv_type = MMC_SET_DRIVER_TYPE_A;
+		else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B)
+			card_drv_type = MMC_SET_DRIVER_TYPE_B;
+		else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
+			card_drv_type = MMC_SET_DRIVER_TYPE_C;
+	} else if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) {
+		host_drv_type = MMC_SET_DRIVER_TYPE_C;
+		if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
+			card_drv_type = MMC_SET_DRIVER_TYPE_C;
+	} else if (!(card->host->caps & MMC_CAP_DRIVER_TYPE_D)) {
+		/*
+		 * If we are here, that means only the default driver type
+		 * B is supported by the host.
+		 */
+		host_drv_type = MMC_SET_DRIVER_TYPE_B;
+		if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B)
+			card_drv_type = MMC_SET_DRIVER_TYPE_B;
+		else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
+			card_drv_type = MMC_SET_DRIVER_TYPE_C;
+	}
+
+	err = mmc_sd_switch(card, 1, 2, card_drv_type, status);
+	if (err)
+		return err;
+
+	if ((status[15] & 0xF) != card_drv_type) {
+		printk(KERN_WARNING "%s: Problem setting driver strength!\n",
+			mmc_hostname(card->host));
+		return 0;
+	}
+
+	mmc_set_driver_type(card->host, host_drv_type);
+
+	return 0;
+}
+
+/*
+ * UHS-I specific initialization procedure
+ */
+static int mmc_sd_init_uhs_card(struct mmc_card *card)
+{
+	int err;
+	u8 *status;
+
+	if (!card->scr.sda_spec3)
+		return 0;
+
+	if (!(card->csd.cmdclass & CCC_SWITCH))
+		return 0;
+
+	status = kmalloc(64, GFP_KERNEL);
+	if (!status) {
+		printk(KERN_ERR "%s: could not allocate a buffer for "
+			"switch capabilities.\n", mmc_hostname(card->host));
+		return -ENOMEM;
+	}
+
+	/* Set 4-bit bus width */
+	if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&
+	    (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
+		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
+		if (err)
+			goto out;
+
+		mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
+	}
+
+	/* Set the driver strength for the card */
+	err = sd_select_driver_type(card, status);
+
+out:
+	kfree(status);
+
+	return err;
+}
+
 MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
 	card->raw_cid[2], card->raw_cid[3]);
 MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
@@ -456,10 +548,10 @@ struct device_type sd_type = {
 /*
  * Fetch CID from card.
  */
-int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
+int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid,
+	u32 *rocr)
 {
 	int err;
-	u32 rocr;
 
 	/*
 	 * Since we're changing the OCR value, we seem to
@@ -493,7 +585,7 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
 		ocr |= 1 << 28;
 
 try_again:
-	err = mmc_send_app_op_cond(host, ocr, &rocr);
+	err = mmc_send_app_op_cond(host, ocr, rocr);
 	if (err)
 		return err;
 
@@ -501,7 +593,8 @@ try_again:
 	 * In case CCS and S18A in the response is set, start Signal Voltage
 	 * Switch procedure. SPI mode doesn't support CMD11.
 	 */
-	if (!mmc_host_is_spi(host) && ((rocr & 0x41000000) == 0x41000000)) {
+	if (!mmc_host_is_spi(host) && rocr &&
+	   ((*rocr & 0x41000000) == 0x41000000)) {
 		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
 		if (err) {
 			ocr &= ~(1 << 24);
@@ -636,11 +729,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 	struct mmc_card *card;
 	int err;
 	u32 cid[4];
+	u32 rocr = 0;
 
 	BUG_ON(!host);
 	WARN_ON(!host->claimed);
 
-	err = mmc_sd_get_cid(host, ocr, cid);
+	err = mmc_sd_get_cid(host, ocr, cid, &rocr);
 	if (err)
 		return err;
 
@@ -693,30 +787,37 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 	if (err)
 		goto free_card;
 
-	/*
-	 * Attempt to change to high-speed (if supported)
-	 */
-	err = mmc_sd_switch_hs(card);
-	if (err > 0)
-		mmc_sd_go_highspeed(card);
-	else if (err)
-		goto free_card;
-
-	/*
-	 * Set bus speed.
-	 */
-	mmc_set_clock(host, mmc_sd_get_max_clock(card));
-
-	/*
-	 * Switch to wider bus (if supported).
-	 */
-	if ((host->caps & MMC_CAP_4_BIT_DATA) &&
-		(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
-		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
+	/* Initialization sequence for UHS-I cards */
+	if (rocr & (1 << 24)) {
+		err = mmc_sd_init_uhs_card(card);
 		if (err)
 			goto free_card;
+	} else {
+		/*
+		 * Attempt to change to high-speed (if supported)
+		 */
+		err = mmc_sd_switch_hs(card);
+		if (err > 0)
+			mmc_sd_go_highspeed(card);
+		else if (err)
+			goto free_card;
+
+		/*
+		 * Set bus speed.
+		 */
+		mmc_set_clock(host, mmc_sd_get_max_clock(card));
 
-		mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
+		/*
+		 * Switch to wider bus (if supported).
+		 */
+		if ((host->caps & MMC_CAP_4_BIT_DATA) &&
+			(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
+			err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
+			if (err)
+				goto free_card;
+
+			mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
+		}
 	}
 
 	host->card = card;
diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h
index 3d8800f..5106b44 100644
--- a/drivers/mmc/core/sd.h
+++ b/drivers/mmc/core/sd.h
@@ -5,7 +5,8 @@
 
 extern struct device_type sd_type;
 
-int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid);
+int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid,
+	u32 *rocr);
 int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card);
 void mmc_decode_cid(struct mmc_card *card);
 int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 1e60959..c4a6614 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -370,7 +370,8 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
 	}
 
 	if (ocr & R4_MEMORY_PRESENT
-	    && mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid) == 0) {
+	    && mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid,
+	    NULL) == 0) {
 		card->type = MMC_TYPE_SD_COMBO;
 
 		if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 86db5e5..fa18b4b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -62,7 +62,7 @@ static void sdhci_dumpregs(struct sdhci_host *host)
 		sdhci_readw(host, SDHCI_TRANSFER_MODE));
 	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
 		sdhci_readl(host, SDHCI_PRESENT_STATE),
-		sdhci_readb(host, SDHCI_HOST_CONTROL));
+		sdhci_readb(host, SDHCI_HOST_CONTROL1));
 	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
 		sdhci_readb(host, SDHCI_POWER_CONTROL),
 		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
@@ -215,18 +215,18 @@ static void sdhci_activate_led(struct sdhci_host *host)
 {
 	u8 ctrl;
 
-	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL1);
 	ctrl |= SDHCI_CTRL_LED;
-	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
 }
 
 static void sdhci_deactivate_led(struct sdhci_host *host)
 {
 	u8 ctrl;
 
-	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL1);
 	ctrl &= ~SDHCI_CTRL_LED;
-	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
 }
 
 #ifdef SDHCI_USE_LEDS_CLASS
@@ -794,14 +794,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
 	 * is ADMA.
 	 */
 	if (host->version >= SDHCI_SPEC_200) {
-		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL1);
 		ctrl &= ~SDHCI_CTRL_DMA_MASK;
 		if ((host->flags & SDHCI_REQ_USE_DMA) &&
 			(host->flags & SDHCI_USE_ADMA))
 			ctrl |= SDHCI_CTRL_ADMA32;
 		else
 			ctrl |= SDHCI_CTRL_SDMA;
-		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
 	}
 
 	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
@@ -1261,7 +1261,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	if (host->ops->platform_8bit_width)
 		host->ops->platform_8bit_width(host, ios->bus_width);
 	else {
-		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL1);
 		if (ios->bus_width == MMC_BUS_WIDTH_8) {
 			ctrl &= ~SDHCI_CTRL_4BITBUS;
 			if (host->version >= SDHCI_SPEC_300)
@@ -1274,10 +1274,10 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			else
 				ctrl &= ~SDHCI_CTRL_4BITBUS;
 		}
-		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
 	}
 
-	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL1);
 
 	if ((ios->timing == MMC_TIMING_SD_HS ||
 	     ios->timing == MMC_TIMING_MMC_HS)
@@ -1286,7 +1286,26 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	else
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
-	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
+
+	if (host->version >= SDHCI_SPEC_300) {
+		u16 ctrl_2;
+
+		ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+		if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
+			/*
+			 * We only need to set Driver Strength if the
+			 * preset value enable is not set.
+			 */
+			ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
+			if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
+				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
+			else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C)
+				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C;
+
+			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+		}
+	}
 
 	/*
 	 * Some (ENE) controllers go apeshit on some ios operation,
@@ -2110,6 +2129,14 @@ int sdhci_add_host(struct sdhci_host *host)
 	if (caps[1] & SDHCI_SUPPORT_DDR50)
 		mmc->caps |= MMC_CAP_UHS_DDR50;
 
+	/* Driver Type(s) (A, C, D) supported by the host */
+	if (caps[1] & SDHCI_DRIVER_TYPE_A)
+		mmc->caps |= MMC_CAP_DRIVER_TYPE_A;
+	if (caps[1] & SDHCI_DRIVER_TYPE_C)
+		mmc->caps |= MMC_CAP_DRIVER_TYPE_C;
+	if (caps[1] & SDHCI_DRIVER_TYPE_D)
+		mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
+
 	ocr_avail = 0;
 	/*
 	 * According to SD Host Controller spec v3.00, if the Host System
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7b53e10..4a64ee0 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -73,7 +73,7 @@
 #define  SDHCI_DATA_LVL_MASK	0x00F00000
 #define   SDHCI_DATA_LVL_SHIFT	20
 
-#define SDHCI_HOST_CONTROL 	0x28
+#define SDHCI_HOST_CONTROL1	0x28
 #define  SDHCI_CTRL_LED		0x01
 #define  SDHCI_CTRL_4BITBUS	0x02
 #define  SDHCI_CTRL_HISPD	0x04
@@ -152,6 +152,12 @@
 
 #define SDHCI_HOST_CONTROL2		0x3E
 #define  SDHCI_CTRL_VDD_180		0x0008
+#define  SDHCI_CTRL_DRV_TYPE_MASK	0x0030
+#define   SDHCI_CTRL_DRV_TYPE_B		0x0000
+#define   SDHCI_CTRL_DRV_TYPE_A		0x0010
+#define   SDHCI_CTRL_DRV_TYPE_C		0x0020
+#define   SDHCI_CTRL_DRV_TYPE_D		0x0030
+#define  SDHCI_CTRL_PRESET_VAL_ENABLE	0x8000
 
 #define SDHCI_CAPABILITIES	0x40
 #define  SDHCI_TIMEOUT_CLK_MASK	0x0000003F
@@ -175,6 +181,9 @@
 #define  SDHCI_SUPPORT_SDR50	0x00000001
 #define  SDHCI_SUPPORT_SDR104	0x00000002
 #define  SDHCI_SUPPORT_DDR50	0x00000004
+#define  SDHCI_DRIVER_TYPE_A	0x00000010
+#define  SDHCI_DRIVER_TYPE_C	0x00000020
+#define  SDHCI_DRIVER_TYPE_D	0x00000040
 
 #define SDHCI_CAPABILITIES_1	0x44
 
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 18b0334..3356b06 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -86,6 +86,10 @@ struct sd_switch_caps {
 	unsigned int		hs_max_dtr;
 	unsigned int		sd3_bus_mode;
 	unsigned int		sd3_drv_type;
+#define SD_DRIVER_TYPE_B	0x01
+#define SD_DRIVER_TYPE_A	0x02
+#define SD_DRIVER_TYPE_C	0x04
+#define SD_DRIVER_TYPE_D	0x08
 	unsigned int		sd3_curr_limit;
 };
 
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index e7f6e64..5625206 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -61,6 +61,13 @@ struct mmc_ios {
 
 #define MMC_SIGNAL_VOLTAGE_330	0
 #define MMC_SIGNAL_VOLTAGE_180	1
+
+	unsigned char	drv_type;		/* driver type (A, B, C, D) */
+
+#define MMC_SET_DRIVER_TYPE_B	0
+#define MMC_SET_DRIVER_TYPE_A	1
+#define MMC_SET_DRIVER_TYPE_C	2
+#define MMC_SET_DRIVER_TYPE_D	3
 };
 
 struct mmc_host_ops {
@@ -188,6 +195,9 @@ struct mmc_host {
 #define MMC_CAP_SET_XPC_330	(1 << 20)	/* Host supports >150mA current at 3.3V */
 #define MMC_CAP_SET_XPC_300	(1 << 21)	/* Host supports >150mA current at 3.0V */
 #define MMC_CAP_SET_XPC_180	(1 << 22)	/* Host supports >150mA current at 1.8V */
+#define MMC_CAP_DRIVER_TYPE_A	(1 << 23)	/* Host supports Driver Type A */
+#define MMC_CAP_DRIVER_TYPE_C	(1 << 24)	/* Host supports Driver Type C */
+#define MMC_CAP_DRIVER_TYPE_D	(1 << 25)	/* Host supports Driver Type D */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
-- 
1.7.1


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

* [PATCH v3 05/12] mmc: sdhci: reset sdclk before setting high speed enable
  2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
                   ` (3 preceding siblings ...)
  2011-04-15 10:38 ` [PATCH v3 04/12] mmc: sd: add support for driver type selection Arindam Nath
@ 2011-04-15 10:38 ` Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 06/12] mmc: sd: add support for uhs bus speed mode selection Arindam Nath
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Arindam Nath @ 2011-04-15 10:38 UTC (permalink / raw)
  To: cjb
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd, Arindam Nath

As per Host Controller spec v3.00, we reset SDCLK before setting
High Speed Enable, and then set it back to avoid generating clock
gliches. Before enabling SDCLK again, we make sure the clock is
stable, so we use sdhci_set_clock().

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
---
 drivers/mmc/host/sdhci.c |   27 ++++++++++++++++++++++++---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index fa18b4b..858cdb8 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1286,13 +1286,12 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	else
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
-	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
-
 	if (host->version >= SDHCI_SPEC_300) {
 		u16 ctrl_2;
 
 		ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 		if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
+			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
 			/*
 			 * We only need to set Driver Strength if the
 			 * preset value enable is not set.
@@ -1304,8 +1303,30 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C;
 
 			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+		} else {
+			/*
+			 * According to SDHC Spec v3.00, if the Preset Value
+			 * Enable in the Host Control 2 register is set, we
+			 * need to reset SD Clock Enable before changing High
+			 * Speed Enable to avoid generating clock gliches.
+			 */
+			u16 clk;
+			unsigned int clock;
+
+			/* Reset SD Clock Enable */
+			clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+			clk &= ~SDHCI_CLOCK_CARD_EN;
+			sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
+
+			/* Re-enable SD Clock */
+			clock = host->clock;
+			host->clock = 0;
+			sdhci_set_clock(host, clock);
 		}
-	}
+	} else
+		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
 
 	/*
 	 * Some (ENE) controllers go apeshit on some ios operation,
-- 
1.7.1


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

* [PATCH v3 06/12] mmc: sd: add support for uhs bus speed mode selection
  2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
                   ` (4 preceding siblings ...)
  2011-04-15 10:38 ` [PATCH v3 05/12] mmc: sdhci: reset sdclk before setting high speed enable Arindam Nath
@ 2011-04-15 10:38 ` Arindam Nath
  2011-04-15 10:38 ` [PATCH v3 07/12] mmc: sd: set current limit for uhs cards Arindam Nath
  2011-04-15 14:06 ` [PATCH v3 00/12] add support for host controller v3.00 Chris Ball
  7 siblings, 0 replies; 27+ messages in thread
From: Arindam Nath @ 2011-04-15 10:38 UTC (permalink / raw)
  To: cjb
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd, Arindam Nath

This patch adds support for setting UHS-I bus speed mode during UHS-I
initialization procedure. Since both the host and card can support
more than one bus speed, we select the highest speed based on both of
their capabilities. First we set the bus speed mode for the card using
CMD6 mode 1, and then we program the host controller to support the
required speed mode. We also set High Speed Enable in case one of the
UHS-I modes is selected. We take care to reset SD clock before setting
UHS mode in the Host Control2 register, and then re-enable it as per
the Host Controller spec v3.00. We then set the clock frequency for
the UHS-I mode selected.

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
---
 drivers/mmc/core/sd.c    |   65 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.c |   40 ++++++++++++++++++++++++++--
 drivers/mmc/host/sdhci.h |    6 ++++
 include/linux/mmc/card.h |   19 +++++++++++++
 include/linux/mmc/host.h |    5 +++
 5 files changed, 132 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index dd0ae2c..bf5710c 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -460,6 +460,66 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
 	return 0;
 }
 
+static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
+{
+	unsigned int bus_speed = 0, timing = 0;
+	int err;
+
+	/*
+	 * If the host doesn't support any of the UHS-I modes, fallback on
+	 * default speed.
+	 */
+	if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
+		return 0;
+
+	if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
+	    (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
+			bus_speed = UHS_SDR104_BUS_SPEED;
+			timing = MMC_TIMING_UHS_SDR104;
+			card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+	} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
+		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
+			bus_speed = UHS_DDR50_BUS_SPEED;
+			timing = MMC_TIMING_UHS_DDR50;
+			card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+		    MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
+		    SD_MODE_UHS_SDR50)) {
+			bus_speed = UHS_SDR50_BUS_SPEED;
+			timing = MMC_TIMING_UHS_SDR50;
+			card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
+		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
+			bus_speed = UHS_SDR25_BUS_SPEED;
+			timing = MMC_TIMING_UHS_SDR25;
+			card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
+		    MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
+		    SD_MODE_UHS_SDR12)) {
+			bus_speed = UHS_SDR12_BUS_SPEED;
+			timing = MMC_TIMING_UHS_SDR12;
+			card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+	}
+
+	card->sd_bus_speed = bus_speed;
+	err = mmc_sd_switch(card, 1, 0, bus_speed, status);
+	if (err)
+		return err;
+
+	if ((status[16] & 0xF) != bus_speed)
+		printk(KERN_WARNING "%s: Problem setting bus speed mode!\n",
+			mmc_hostname(card->host));
+	else {
+		mmc_set_timing(card->host, timing);
+		mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
+	}
+
+	return 0;
+}
+
 /*
  * UHS-I specific initialization procedure
  */
@@ -493,6 +553,11 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
 
 	/* Set the driver strength for the card */
 	err = sd_select_driver_type(card, status);
+	if (err)
+		goto out;
+
+	/* Set bus speed mode of the card */
+	err = sd_set_bus_speed_mode(card, status);
 
 out:
 	kfree(status);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 858cdb8..7a4fcb5 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1287,7 +1287,16 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
 	if (host->version >= SDHCI_SPEC_300) {
-		u16 ctrl_2;
+		u16 clk, ctrl_2;
+		unsigned int clock;
+
+		/* In case of UHS-I modes, set High Speed Enable */
+		if ((ios->timing == MMC_TIMING_UHS_SDR50) ||
+		    (ios->timing == MMC_TIMING_UHS_SDR104) ||
+		    (ios->timing == MMC_TIMING_UHS_DDR50) ||
+		    (ios->timing == MMC_TIMING_UHS_SDR25) ||
+		    (ios->timing == MMC_TIMING_UHS_SDR12))
+			ctrl |= SDHCI_CTRL_HISPD;
 
 		ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 		if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
@@ -1310,8 +1319,6 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			 * need to reset SD Clock Enable before changing High
 			 * Speed Enable to avoid generating clock gliches.
 			 */
-			u16 clk;
-			unsigned int clock;
 
 			/* Reset SD Clock Enable */
 			clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
@@ -1325,6 +1332,33 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			host->clock = 0;
 			sdhci_set_clock(host, clock);
 		}
+
+		ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+		/* Select Bus Speed Mode for host */
+		ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
+		if (ios->timing == MMC_TIMING_UHS_SDR12)
+			ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
+		else if (ios->timing == MMC_TIMING_UHS_SDR25)
+			ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
+		else if (ios->timing == MMC_TIMING_UHS_SDR50)
+			ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
+		else if (ios->timing == MMC_TIMING_UHS_SDR104)
+			ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
+		else if (ios->timing == MMC_TIMING_UHS_DDR50)
+			ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
+
+		/* Reset SD Clock Enable */
+		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+		clk &= ~SDHCI_CLOCK_CARD_EN;
+		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+		sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+
+		/* Re-enable SD Clock */
+		clock = host->clock;
+		host->clock = 0;
+		sdhci_set_clock(host, clock);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL1);
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 4a64ee0..c60d5ca 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -151,6 +151,12 @@
 #define SDHCI_ACMD12_ERR	0x3C
 
 #define SDHCI_HOST_CONTROL2		0x3E
+#define  SDHCI_CTRL_UHS_MASK		0x0007
+#define   SDHCI_CTRL_UHS_SDR12		0x0000
+#define   SDHCI_CTRL_UHS_SDR25		0x0001
+#define   SDHCI_CTRL_UHS_SDR50		0x0002
+#define   SDHCI_CTRL_UHS_SDR104		0x0003
+#define   SDHCI_CTRL_UHS_DDR50		0x0004
 #define  SDHCI_CTRL_VDD_180		0x0008
 #define  SDHCI_CTRL_DRV_TYPE_MASK	0x0030
 #define   SDHCI_CTRL_DRV_TYPE_B		0x0000
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 3356b06..6a47d35 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -84,7 +84,24 @@ struct sd_ssr {
 
 struct sd_switch_caps {
 	unsigned int		hs_max_dtr;
+	unsigned int		uhs_max_dtr;
+#define UHS_SDR104_MAX_DTR	208000000
+#define UHS_SDR50_MAX_DTR	100000000
+#define UHS_DDR50_MAX_DTR	50000000
+#define UHS_SDR25_MAX_DTR	UHS_DDR50_MAX_DTR
+#define UHS_SDR12_MAX_DTR	25000000
 	unsigned int		sd3_bus_mode;
+#define UHS_SDR12_BUS_SPEED	0
+#define UHS_SDR25_BUS_SPEED	1
+#define UHS_SDR50_BUS_SPEED	2
+#define UHS_SDR104_BUS_SPEED	3
+#define UHS_DDR50_BUS_SPEED	4
+
+#define SD_MODE_UHS_SDR12	(1 << UHS_SDR12_BUS_SPEED)
+#define SD_MODE_UHS_SDR25	(1 << UHS_SDR25_BUS_SPEED)
+#define SD_MODE_UHS_SDR50	(1 << UHS_SDR50_BUS_SPEED)
+#define SD_MODE_UHS_SDR104	(1 << UHS_SDR104_BUS_SPEED)
+#define SD_MODE_UHS_DDR50	(1 << UHS_DDR50_BUS_SPEED)
 	unsigned int		sd3_drv_type;
 #define SD_DRIVER_TYPE_B	0x01
 #define SD_DRIVER_TYPE_A	0x02
@@ -169,6 +186,8 @@ struct mmc_card {
 	const char		**info;		/* info strings */
 	struct sdio_func_tuple	*tuples;	/* unknown common tuples */
 
+	unsigned int		sd_bus_speed;	/* Bus Speed Mode set for the card */
+
 	struct dentry		*debugfs_root;
 };
 
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 5625206..2f20eb5 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -50,6 +50,11 @@ struct mmc_ios {
 #define MMC_TIMING_LEGACY	0
 #define MMC_TIMING_MMC_HS	1
 #define MMC_TIMING_SD_HS	2
+#define MMC_TIMING_UHS_SDR12	MMC_TIMING_LEGACY
+#define MMC_TIMING_UHS_SDR25	MMC_TIMING_SD_HS
+#define MMC_TIMING_UHS_SDR50	3
+#define MMC_TIMING_UHS_SDR104	4
+#define MMC_TIMING_UHS_DDR50	5
 
 	unsigned char	ddr;			/* dual data rate used */
 
-- 
1.7.1


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

* [PATCH v3 07/12] mmc: sd: set current limit for uhs cards
  2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
                   ` (5 preceding siblings ...)
  2011-04-15 10:38 ` [PATCH v3 06/12] mmc: sd: add support for uhs bus speed mode selection Arindam Nath
@ 2011-04-15 10:38 ` Arindam Nath
  2011-04-15 14:06 ` [PATCH v3 00/12] add support for host controller v3.00 Chris Ball
  7 siblings, 0 replies; 27+ messages in thread
From: Arindam Nath @ 2011-04-15 10:38 UTC (permalink / raw)
  To: cjb
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd, Arindam Nath

We decide on the current limit to be set for the card based on the
Capability of Host Controller to provide current at 1.8V signalling,
and the maximum current limit of the card as indicated by CMD6
mode 0. We then set the current limit for the card using CMD6 mode 1.
As per the Physical Layer Spec v3.01, the current limit switch is
only applicable for SDR50, SDR104, and DDR50 bus speed modes. For
other UHS-I modes, we set the default current limit of 200mA.

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
---
 drivers/mmc/core/sd.c    |   63 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.c |   10 +++++++
 include/linux/mmc/card.h |    9 ++++++
 include/linux/mmc/host.h |    4 +++
 4 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index bf5710c..001d2e8 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -520,6 +520,64 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
 	return 0;
 }
 
+static int sd_set_current_limit(struct mmc_card *card, u8 *status)
+{
+	int current_limit = 0;
+	int err;
+
+	/*
+	 * Current limit switch is only defined for SDR50, SDR104, and DDR50
+	 * bus speed modes. For other bus speed modes, we set the default
+	 * current limit of 200mA.
+	 */
+	if ((card->sd_bus_speed == UHS_SDR50_BUS_SPEED) ||
+	    (card->sd_bus_speed == UHS_SDR104_BUS_SPEED) ||
+	    (card->sd_bus_speed == UHS_DDR50_BUS_SPEED)) {
+		if (card->host->caps & MMC_CAP_MAX_CURRENT_800) {
+			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
+				current_limit = SD_SET_CURRENT_LIMIT_800;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_600)
+				current_limit = SD_SET_CURRENT_LIMIT_600;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_400)
+				current_limit = SD_SET_CURRENT_LIMIT_400;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_200)
+				current_limit = SD_SET_CURRENT_LIMIT_200;
+		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_600) {
+			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
+				current_limit = SD_SET_CURRENT_LIMIT_600;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_400)
+				current_limit = SD_SET_CURRENT_LIMIT_400;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_200)
+				current_limit = SD_SET_CURRENT_LIMIT_200;
+		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_400) {
+			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
+				current_limit = SD_SET_CURRENT_LIMIT_400;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_200)
+				current_limit = SD_SET_CURRENT_LIMIT_200;
+		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_200) {
+			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
+				current_limit = SD_SET_CURRENT_LIMIT_200;
+		}
+	} else
+		current_limit = SD_SET_CURRENT_LIMIT_200;
+
+	err = mmc_sd_switch(card, 1, 3, current_limit, status);
+	if (err)
+		return err;
+
+	if (((status[15] >> 4) & 0x0F) != current_limit)
+		printk(KERN_WARNING "%s: Problem setting current limit!\n",
+			mmc_hostname(card->host));
+
+	return 0;
+}
+
 /*
  * UHS-I specific initialization procedure
  */
@@ -558,6 +616,11 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
 
 	/* Set bus speed mode of the card */
 	err = sd_set_bus_speed_mode(card, status);
+	if (err)
+		goto out;
+
+	/* Set current limit for the card */
+	err = sd_set_current_limit(card, status);
 
 out:
 	kfree(status);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 7a4fcb5..21b2290 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2240,6 +2240,16 @@ int sdhci_add_host(struct sdhci_host *host)
 
 		if (max_current_180 > 150)
 			mmc->caps |= MMC_CAP_SET_XPC_180;
+
+		/* Maximum current capabilities of the host at 1.8V */
+		if (max_current_180 >= 800)
+			mmc->caps |= MMC_CAP_MAX_CURRENT_800;
+		else if (max_current_180 >= 600)
+			mmc->caps |= MMC_CAP_MAX_CURRENT_600;
+		else if (max_current_180 >= 400)
+			mmc->caps |= MMC_CAP_MAX_CURRENT_400;
+		else
+			mmc->caps |= MMC_CAP_MAX_CURRENT_200;
 	}
 
 	mmc->ocr_avail = ocr_avail;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 6a47d35..d7f81a7 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -108,6 +108,15 @@ struct sd_switch_caps {
 #define SD_DRIVER_TYPE_C	0x04
 #define SD_DRIVER_TYPE_D	0x08
 	unsigned int		sd3_curr_limit;
+#define SD_SET_CURRENT_LIMIT_200	0
+#define SD_SET_CURRENT_LIMIT_400	1
+#define SD_SET_CURRENT_LIMIT_600	2
+#define SD_SET_CURRENT_LIMIT_800	3
+
+#define SD_MAX_CURRENT_200	(1 << SD_SET_CURRENT_LIMIT_200)
+#define SD_MAX_CURRENT_400	(1 << SD_SET_CURRENT_LIMIT_400)
+#define SD_MAX_CURRENT_600	(1 << SD_SET_CURRENT_LIMIT_600)
+#define SD_MAX_CURRENT_800	(1 << SD_SET_CURRENT_LIMIT_800)
 };
 
 struct sdio_cccr {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 2f20eb5..1a73e38 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -203,6 +203,10 @@ struct mmc_host {
 #define MMC_CAP_DRIVER_TYPE_A	(1 << 23)	/* Host supports Driver Type A */
 #define MMC_CAP_DRIVER_TYPE_C	(1 << 24)	/* Host supports Driver Type C */
 #define MMC_CAP_DRIVER_TYPE_D	(1 << 25)	/* Host supports Driver Type D */
+#define MMC_CAP_MAX_CURRENT_200	(1 << 26)	/* Host max current limit is 200mA */
+#define MMC_CAP_MAX_CURRENT_400	(1 << 27)	/* Host max current limit is 400mA */
+#define MMC_CAP_MAX_CURRENT_600	(1 << 28)	/* Host max current limit is 600mA */
+#define MMC_CAP_MAX_CURRENT_800	(1 << 29)	/* Host max current limit is 800mA */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
-- 
1.7.1


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

* Re: [PATCH v3 00/12] add support for host controller v3.00
  2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
                   ` (6 preceding siblings ...)
  2011-04-15 10:38 ` [PATCH v3 07/12] mmc: sd: set current limit for uhs cards Arindam Nath
@ 2011-04-15 14:06 ` Chris Ball
  2011-04-15 14:06   ` Nath, Arindam
  2011-04-26  5:52   ` Nath, Arindam
  7 siblings, 2 replies; 27+ messages in thread
From: Chris Ball @ 2011-04-15 14:06 UTC (permalink / raw)
  To: Arindam Nath
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, henry.su, aaron.lu,
	anath.amd

Hi Arindam,

On Fri, Apr 15 2011, Arindam Nath wrote:
> V3

Thanks very much for reposting this!  I know it's a lot of work to keep
track of so many comments and changes.

I've checked that this applies to mmc-next and doesn't add any compile
warnings, and the patch quality (particularly your use of comments)
looks excellent.  I'll wait a week for further comments and Tested-bys,
and then look at whether we should push the series to mmc-next as-is
or wait for another revision.

Thanks,

- Chris.
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

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

* RE: [PATCH v3 00/12] add support for host controller v3.00
  2011-04-15 14:06 ` [PATCH v3 00/12] add support for host controller v3.00 Chris Ball
@ 2011-04-15 14:06   ` Nath, Arindam
  2011-04-26  5:52   ` Nath, Arindam
  1 sibling, 0 replies; 27+ messages in thread
From: Nath, Arindam @ 2011-04-15 14:06 UTC (permalink / raw)
  To: Chris Ball
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, Su, Henry, Lu, Aaron,
	anath.amd

Hi Chris,


> -----Original Message-----
> From: Chris Ball [mailto:cjb@laptop.org]
> Sent: Friday, April 15, 2011 7:36 PM
> To: Nath, Arindam
> Cc: linux-mmc@vger.kernel.org; subhashj@codeaurora.org;
> prakity@marvell.com; zhangfei.gao@gmail.com; Su, Henry; Lu, Aaron;
> anath.amd@gmail.com
> Subject: Re: [PATCH v3 00/12] add support for host controller v3.00
> 
> Hi Arindam,
> 
> On Fri, Apr 15 2011, Arindam Nath wrote:
> > V3
> 
> Thanks very much for reposting this!  I know it's a lot of work to keep
> track of so many comments and changes.
> 
> I've checked that this applies to mmc-next and doesn't add any compile
> warnings, and the patch quality (particularly your use of comments)
> looks excellent.  I'll wait a week for further comments and Tested-bys,
> and then look at whether we should push the series to mmc-next as-is
> or wait for another revision.

Thanks for the feedback.

Regards,
Arindam

> 
> Thanks,
> 
> - Chris.
> --
> Chris Ball   <cjb@laptop.org>   <http://printf.net/>
> One Laptop Per Child



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

* Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
       [not found]         ` <BANLkTimfQo7wJ3_ecs64VSp7xKJrjYdJ3w@mail.gmail.com>
@ 2011-04-15 20:04           ` Andrei Warkentin
  2011-04-16  5:25             ` Nath, Arindam
  2011-04-16  6:17             ` Subhash Jadavani
  0 siblings, 2 replies; 27+ messages in thread
From: Andrei Warkentin @ 2011-04-15 20:04 UTC (permalink / raw)
  To: Nath, Arindam, linux-mmc

+linux-mmc

On Fri, Apr 15, 2011 at 3:03 PM, Andrei Warkentin <andreiw@motorola.com> wrote:
> On Fri, Apr 15, 2011 at 1:57 PM, Andrei Warkentin <andreiw@motorola.com> wrote:
>> Hi Arindam,
>>
>> On Fri, Apr 15, 2011 at 12:34 PM, Nath, Arindam <Arindam.Nath@amd.com> wrote:
>>> Hi Andrei,
>>
>>>>
>>>> I've recently posted changes relating to CMD23 support in block layer.
>>>> Effectively, in order to support hosts with and without Auto-CMD23
>>>> (and with proper error handling) there is a new MMC_CAP_CMD23 for the
>>>> host, and a new field "mmc_command sbc" inside the mmc_request.
>>>>
>>>> I also have a patch enabling CMD23 use with an SDHCI host (< 3.00).
>>>>
>>>> Could you be so kind as to rebase this patch on top of that? You're
>>>> doing a lot of things here that you really shouldn't be (like
>>>> enforcing policy on what gets sent to cards, knowing what's connected
>>>> to the host, conflicting with reliable writes code if Auto-CMD23 was
>>>> enabled for MMCs, not supporting MMCs which always have
>>>> SET_BLOCK_COUNT).
>>>
>>> Our Host Controller is complaint to the Host Controller Spec v3.00, and since Auto CMD23 is a feature added to the HC, I thought it would be better to make this feature part of sdhci and not the core/block layer.
>>>
>>> But in case you want Auto CMD23 to be implemented in a different way, it would rather be great if you help me implement in your own way, and then probably based on community suggestions, we can keep either of the patch.
>>
>> Let me clarify:
>>
>> 1) Sending CMD23 on multiblock transfers is not a an SDHCI specific
>> feature. It's a feature of MMC cards and SD cards operating at UHS104
>> or greater.
>> 2) CMD23-bounded multi block writes are a generic problem already -
>> eMMC reliable writes, for example.
>> 3) CMD23 is not bound to any specific controller - so having generic
>> code to allow execution of CMD23 will speed up transfers (and enable
>> certain features) on any host.
>> 4) Auto-CMD is a specific SDHCI enhancement, meant to reduce overhead
>> of sending CMD23.
>> 5) Host controller has to be aware of CMD23 sending, because on an
>> error STOP has to be sent, and without error, no STOP has to be sent.
>>
>> You are in a unique position where you have functional SDHCI 3.0
>> hardware and are able to test Auto-CMD23. Please look at the patch set
>> I sent - it should be trivial to extend current SDHCI patch to use
>> Auto-CMD23 when possible instead of sending mmc_request->sbc.
>> Basically, I have a generic improvement that affects all host
>> controllers. Auto-CMD23 is an optimization of that for SDHCI 3.0.
>>
>> Your current patch to enable Auto-CMD23 is not useful as far as non-SD
>> cards are concerned and you push way to much policy and
>> non-host-related complexity into it.
>>
>> Thanks,
>> A
>>
>
> More clarification:
>
> The block layer patch may change slightly (whitelisting/blacklisting
> certain MMC devices for using CMD23 for multiblock transfers), but the
> changes to mmc_request and SDHCI are not. So feel free to rebase it
> without waiting for anything. If you need help, I will gladly help
> you, but keep in mind I don't have SDHCI 3.0 hardware around.
>
> Thanks,
> A
>

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

* RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-15 20:04           ` Andrei Warkentin
@ 2011-04-16  5:25             ` Nath, Arindam
  2011-04-16  9:07               ` Andrei Warkentin
  2011-04-16  6:17             ` Subhash Jadavani
  1 sibling, 1 reply; 27+ messages in thread
From: Nath, Arindam @ 2011-04-16  5:25 UTC (permalink / raw)
  To: Andrei Warkentin, linux-mmc

Hi Andrei,


> -----Original Message-----
> From: Andrei Warkentin [mailto:andreiw@motorola.com]
> Sent: Saturday, April 16, 2011 1:34 AM
> To: Nath, Arindam; linux-mmc@vger.kernel.org
> Subject: Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> 
> +linux-mmc
> 
> On Fri, Apr 15, 2011 at 3:03 PM, Andrei Warkentin
> <andreiw@motorola.com> wrote:
> > On Fri, Apr 15, 2011 at 1:57 PM, Andrei Warkentin
> <andreiw@motorola.com> wrote:
> >> Hi Arindam,
> >>
> >> On Fri, Apr 15, 2011 at 12:34 PM, Nath, Arindam
> <Arindam.Nath@amd.com> wrote:
> >>> Hi Andrei,
> >>
> >>>>
> >>>> I've recently posted changes relating to CMD23 support in block
> layer.
> >>>> Effectively, in order to support hosts with and without Auto-CMD23
> >>>> (and with proper error handling) there is a new MMC_CAP_CMD23 for
> the
> >>>> host, and a new field "mmc_command sbc" inside the mmc_request.
> >>>>
> >>>> I also have a patch enabling CMD23 use with an SDHCI host (<
> 3.00).
> >>>>
> >>>> Could you be so kind as to rebase this patch on top of that?
> You're
> >>>> doing a lot of things here that you really shouldn't be (like
> >>>> enforcing policy on what gets sent to cards, knowing what's
> connected
> >>>> to the host, conflicting with reliable writes code if Auto-CMD23
> was
> >>>> enabled for MMCs, not supporting MMCs which always have
> >>>> SET_BLOCK_COUNT).
> >>>
> >>> Our Host Controller is complaint to the Host Controller Spec v3.00,
> and since Auto CMD23 is a feature added to the HC, I thought it would
> be better to make this feature part of sdhci and not the core/block
> layer.
> >>>
> >>> But in case you want Auto CMD23 to be implemented in a different
> way, it would rather be great if you help me implement in your own way,
> and then probably based on community suggestions, we can keep either of
> the patch.
> >>
> >> Let me clarify:
> >>
> >> 1) Sending CMD23 on multiblock transfers is not a an SDHCI specific
> >> feature. It's a feature of MMC cards and SD cards operating at
> UHS104
> >> or greater.
> >> 2) CMD23-bounded multi block writes are a generic problem already -
> >> eMMC reliable writes, for example.
> >> 3) CMD23 is not bound to any specific controller - so having generic
> >> code to allow execution of CMD23 will speed up transfers (and enable
> >> certain features) on any host.
> >> 4) Auto-CMD is a specific SDHCI enhancement, meant to reduce
> overhead
> >> of sending CMD23.
> >> 5) Host controller has to be aware of CMD23 sending, because on an
> >> error STOP has to be sent, and without error, no STOP has to be
> sent.
> >>
> >> You are in a unique position where you have functional SDHCI 3.0
> >> hardware and are able to test Auto-CMD23. Please look at the patch
> set
> >> I sent - it should be trivial to extend current SDHCI patch to use
> >> Auto-CMD23 when possible instead of sending mmc_request->sbc.
> >> Basically, I have a generic improvement that affects all host
> >> controllers. Auto-CMD23 is an optimization of that for SDHCI 3.0.
> >>
> >> Your current patch to enable Auto-CMD23 is not useful as far as non-
> SD
> >> cards are concerned and you push way to much policy and
> >> non-host-related complexity into it.
> >>
> >> Thanks,
> >> A
> >>
> >
> > More clarification:
> >
> > The block layer patch may change slightly (whitelisting/blacklisting
> > certain MMC devices for using CMD23 for multiblock transfers), but
> the
> > changes to mmc_request and SDHCI are not. So feel free to rebase it
> > without waiting for anything. If you need help, I will gladly help
> > you, but keep in mind I don't have SDHCI 3.0 hardware around.

I saw in one of the community threads that you also have a patch ready for supporting Auto CMD23 for SDHCI. Can you share the same with us? I would like to take a look at your patch first before deciding whether it would make sense for controllers which comply with Host Controller Spec v3.00.

Thanks,
Arindam

> >
> > Thanks,
> > A
> >



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

* RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-15 20:04           ` Andrei Warkentin
  2011-04-16  5:25             ` Nath, Arindam
@ 2011-04-16  6:17             ` Subhash Jadavani
  2011-04-16  6:25               ` Nath, Arindam
  1 sibling, 1 reply; 27+ messages in thread
From: Subhash Jadavani @ 2011-04-16  6:17 UTC (permalink / raw)
  To: 'Andrei Warkentin', 'Nath, Arindam', linux-mmc

[-- Attachment #1: Type: text/plain, Size: 4215 bytes --]

> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Andrei Warkentin
> Sent: Saturday, April 16, 2011 1:34 AM
> To: Nath, Arindam; linux-mmc@vger.kernel.org
> Subject: Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> 
> +linux-mmc
> 
> On Fri, Apr 15, 2011 at 3:03 PM, Andrei Warkentin
> <andreiw@motorola.com> wrote:
> > On Fri, Apr 15, 2011 at 1:57 PM, Andrei Warkentin
> <andreiw@motorola.com> wrote:
> >> Hi Arindam,
> >>
> >> On Fri, Apr 15, 2011 at 12:34 PM, Nath, Arindam
> <Arindam.Nath@amd.com> wrote:
> >>> Hi Andrei,
> >>
> >>>>
> >>>> I've recently posted changes relating to CMD23 support in block
> layer.
> >>>> Effectively, in order to support hosts with and without Auto-CMD23
> >>>> (and with proper error handling) there is a new MMC_CAP_CMD23 for
> the
> >>>> host, and a new field "mmc_command sbc" inside the mmc_request.
> >>>>
> >>>> I also have a patch enabling CMD23 use with an SDHCI host (<
> 3.00).
> >>>>
> >>>> Could you be so kind as to rebase this patch on top of that?
> You're
> >>>> doing a lot of things here that you really shouldn't be (like
> >>>> enforcing policy on what gets sent to cards, knowing what's
> connected
> >>>> to the host, conflicting with reliable writes code if Auto-CMD23
> was
> >>>> enabled for MMCs, not supporting MMCs which always have
> >>>> SET_BLOCK_COUNT).
> >>>
> >>> Our Host Controller is complaint to the Host Controller Spec v3.00,
> and since Auto CMD23 is a feature added to the HC, I thought it would
> be better to make this feature part of sdhci and not the core/block
> layer.
> >>>
> >>> But in case you want Auto CMD23 to be implemented in a different
> way, it would rather be great if you help me implement in your own way,
> and then probably based on community suggestions, we can keep either of
> the patch.
> >>
> >> Let me clarify:
> >>
> >> 1) Sending CMD23 on multiblock transfers is not a an SDHCI specific
> >> feature. It's a feature of MMC cards and SD cards operating at
> UHS104
> >> or greater.
> >> 2) CMD23-bounded multi block writes are a generic problem already -
> >> eMMC reliable writes, for example.
> >> 3) CMD23 is not bound to any specific controller - so having generic
> >> code to allow execution of CMD23 will speed up transfers (and enable
> >> certain features) on any host.

These are the same point I had discussed earlier with Arindam. Please check
the attached mails.

Yes, I would also agree with Andrei that all generic code related to CMD23
handling should be in core/block layer. Internally host controller driver
can handle CMD23 differently as not all host controller support AUTO-CMD23.

> >> 4) Auto-CMD is a specific SDHCI enhancement, meant to reduce
> overhead
> >> of sending CMD23.
> >> 5) Host controller has to be aware of CMD23 sending, because on an
> >> error STOP has to be sent, and without error, no STOP has to be
> sent.
> >>
> >> You are in a unique position where you have functional SDHCI 3.0
> >> hardware and are able to test Auto-CMD23. Please look at the patch
> set
> >> I sent - it should be trivial to extend current SDHCI patch to use
> >> Auto-CMD23 when possible instead of sending mmc_request->sbc.
> >> Basically, I have a generic improvement that affects all host
> >> controllers. Auto-CMD23 is an optimization of that for SDHCI 3.0.
> >>
> >> Your current patch to enable Auto-CMD23 is not useful as far as non-
> SD
> >> cards are concerned and you push way to much policy and
> >> non-host-related complexity into it.
> >>
> >> Thanks,
> >> A
> >>
> >
> > More clarification:
> >
> > The block layer patch may change slightly (whitelisting/blacklisting
> > certain MMC devices for using CMD23 for multiblock transfers), but
> the
> > changes to mmc_request and SDHCI are not. So feel free to rebase it
> > without waiting for anything. If you need help, I will gladly help
> > you, but keep in mind I don't have SDHCI 3.0 hardware around.
> >
> > Thanks,
> > A
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: Type: message/rfc822, Size: 15337 bytes --]

From: "Subhash Jadavani" <subhashj@codeaurora.org>
To: "'Nath, Arindam'" <Arindam.Nath@amd.com>, <cjb@laptop.org>
Cc: <zhangfei.gao@gmail.com>, <prakity@marvell.com>, <linux-mmc@vger.kernel.org>, "'Su, Henry'" <Henry.Su@amd.com>, "'Lu, Aaron'" <Aaron.Lu@amd.com>, <anath.amd@gmail.com>
Subject: RE: [PATCH v2 01/12] mmc: sdhci: add support for auto CMD23
Date: Tue, 15 Mar 2011 17:22:31 +0530
Message-ID: <002901cbe307$7a1e6680$6e5b3380$@org>



> -----Original Message-----
> From: Nath, Arindam [mailto:Arindam.Nath@amd.com]
> Sent: Tuesday, March 15, 2011 5:05 PM
> To: Subhash Jadavani; cjb@laptop.org
> Cc: zhangfei.gao@gmail.com; prakity@marvell.com; linux-
> mmc@vger.kernel.org; Su, Henry; Lu, Aaron; anath.amd@gmail.com
> Subject: RE: [PATCH v2 01/12] mmc: sdhci: add support for auto CMD23
> 
> Hi Subhash,
> 
> 
> > -----Original Message-----
> > From: Subhash Jadavani [mailto:subhashj@codeaurora.org]
> > Sent: Tuesday, March 15, 2011 4:54 PM
> > To: Nath, Arindam; cjb@laptop.org
> > Cc: zhangfei.gao@gmail.com; prakity@marvell.com; linux-
> > mmc@vger.kernel.org; Su, Henry; Lu, Aaron; anath.amd@gmail.com
> > Subject: RE: [PATCH v2 01/12] mmc: sdhci: add support for auto CMD23
> >
> > Arindam,
> >
> > Capability to send CMD23 automatically is something specific to your
> > controller.
> 
> Auto CMD23 is different from ACMD23. Auto CMD23 is a feature added into
> Host Controller Spec v3.00, and the code follows the procedure to check
> the 4 preconditions required to enable Host to send CMD23
> automatically. I had similar discussion on the community with Arnd few
> weeks back, and we agreed that this should be part of controller
> specific code.

I am not talking about ACMD23 which is SET_WR_BLK_ERASE_COUNT. I am talking
about newly added CMD23 (SET_BLOCK_COUNT) command in SD3.0. Shouldn't the
logic to send this command be part of generic mmc layers (block/core) rather
than at host controller driver level. It's good that your controller have
the hw capability to send the CMD23 automatically but what about for
controllers which doesn't have this type of capability available? Then it
has to rely on the block/core layer to send the CMD23 before CMD19/CMD25. I
think this should be part of block/core layer functionality in order to be
SD3.01 spec compliant.

> 
> Thanks,
> Arindam
> 
> > CMD23 (SET_BLOCK_COUNT) is a new command added in SD3.0 spec and
> > mandatory
> > for SDR104 mode. Why are you not adding this command in core/block
> > layer
> > before sending multi byte read command to host controller driver?
> >
> > Regards,
> > Subhash
> >
> > > -----Original Message-----
> > > From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> > > owner@vger.kernel.org] On Behalf Of Arindam Nath
> > > Sent: Friday, March 04, 2011 5:03 PM
> > > To: cjb@laptop.org
> > > Cc: zhangfei.gao@gmail.com; prakity@marvell.com;
> > > subhashj@codeaurora.org; linux-mmc@vger.kernel.org;
> henry.su@amd.com;
> > > aaron.lu@amd.com; anath.amd@gmail.com; Arindam Nath
> > > Subject: [PATCH v2 01/12] mmc: sdhci: add support for auto CMD23
> > >
> > > Host Controller v3.00 and later support Auto CMD23 in the Transfer
> > > Mode register. Since Auto CMD23 can be used with or without DMA,
> > > and if used with DMA, it should _only_ be ADMA, we check against
> > > SDHCI_USE_SDMA not being set. This flag is reset when
> SDHCI_USE_ADMA
> > > is set.
> > >
> > > A new definition for SDHCI_ARGUMENT2 register has been added in
> v3.00
> > > spec, which is the same as SDHCI_DMA_ADDRESS. We program the block
> > > count for CMD23 in SDHCI_ARGUMENT2, so we don't need CMD12 to stop
> > > multiple block transfers. But during error recovery procedure, we
> > will
> > > need to send Abort command, so we use a variable saved_abort_cmd to
> > > save the stop command to be used later.
> > >
> > > Two bits are added to SCR register as per the Physical Layer Spec
> > > v3.01,
> > > which specify whether the card supports CMD20 and/or CMD23. We use
> > this
> > > as one of the conditions to decide whether to enable Auto CMD23 or
> > not.
> > >
> > > Signed-off-by: Arindam Nath <arindam.nath@amd.com>
> > > ---
> > >  drivers/mmc/core/sd.c     |    6 ++++
> > >  drivers/mmc/host/sdhci.c  |   69
> > > +++++++++++++++++++++++++++++++++++++++++---
> > >  drivers/mmc/host/sdhci.h  |    2 +
> > >  include/linux/mmc/card.h  |    4 ++
> > >  include/linux/mmc/sd.h    |    2 +-
> > >  include/linux/mmc/sdhci.h |    2 +
> > >  6 files changed, 79 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> > > index d18c32b..b3f8a3c 100644
> > > --- a/drivers/mmc/core/sd.c
> > > +++ b/drivers/mmc/core/sd.c
> > > @@ -188,6 +188,12 @@ static int mmc_decode_scr(struct mmc_card
> *card)
> > >
> > >  	scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
> > >  	scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
> > > +	if (scr->sda_vsn == SCR_SPEC_VER_2) {
> > > +		/* Check if Physical Layer Spec v3.0 is supported*/
> > > +		scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
> > > +		if (scr->sda_spec3)
> > > +			scr->cmd_support = UNSTUFF_BITS(resp, 32, 2);
> > > +	}
> > >
> > >  	if (UNSTUFF_BITS(resp, 55, 1))
> > >  		card->erased_byte = 0xFF;
> > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> > > index 9e15f41..8914a25 100644
> > > --- a/drivers/mmc/host/sdhci.c
> > > +++ b/drivers/mmc/host/sdhci.c
> > > @@ -25,6 +25,7 @@
> > >
> > >  #include <linux/mmc/mmc.h>
> > >  #include <linux/mmc/host.h>
> > > +#include <linux/mmc/card.h>
> > >
> > >  #include "sdhci.h"
> > >
> > > @@ -812,6 +813,30 @@ static void sdhci_prepare_data(struct
> sdhci_host
> > > *host, struct mmc_data *data)
> > >  	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
> > >  }
> > >
> > > +/*
> > > + * Does the Host Controller support Auto CMD23?
> > > + *
> > > + * There are four preconditions for Auto CMD23 to be supported:
> > > + *  1. Host Controller v3.00 or later
> > > + *  2. Card supports CMD23
> > > + *  3. If DMA is used, it should be ADMA
> > > + *  4. Only when CMD18 or CMD25 is issued
> > > + */
> > > +static int sdhci_host_auto_cmd23_supported(struct sdhci_host
> *host,
> > > +	struct mmc_request *mrq)
> > > +{
> > > +	struct mmc_card *card = host->mmc->card;
> > > +
> > > +	if ((host->version >= SDHCI_SPEC_300) &&
> > > +	   card && (card->scr.cmd_support & SD_SCR_CMD23_SUPPORT) &&
> > > +	   !(host->flags & SDHCI_USE_SDMA) &&
> > > +	   ((mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK) ||
> > > +	   (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK)))
> > > +		return 1;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  static void sdhci_set_transfer_mode(struct sdhci_host *host,
> > >  	struct mmc_data *data)
> > >  {
> > > @@ -825,10 +850,21 @@ static void sdhci_set_transfer_mode(struct
> > > sdhci_host *host,
> > >  	mode = SDHCI_TRNS_BLK_CNT_EN;
> > >  	if (data->blocks > 1) {
> > >  		if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
> > > -			mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
> > > -		else
> > > -			mode |= SDHCI_TRNS_MULTI;
> > > +			mode |= SDHCI_TRNS_ACMD12;
> > > +		else if (sdhci_host_auto_cmd23_supported(host, host->mrq))
> > > {
> > > +			/*
> > > +			 * Host Controller v3.00 can automatically send
> > CMD23
> > > +			 * before CMD18 or CMD25. For that, we need to
> > enable
> > > +			 * Auto CMD23 in the Transfer Mode register and
> > > +			 * program the block count in Argument 2 register.
> > > +			 */
> > > +			mode |= SDHCI_TRNS_AUTO_CMD23;
> > > +			sdhci_writel(host, data->blocks, SDHCI_ARGUMENT2);
> > > +		}
> > > +
> > > +		mode |= SDHCI_TRNS_MULTI;
> > >  	}
> > > +
> > >  	if (data->flags & MMC_DATA_READ)
> > >  		mode |= SDHCI_TRNS_READ;
> > >  	if (host->flags & SDHCI_REQ_USE_DMA)
> > > @@ -1131,6 +1167,23 @@ static void sdhci_request(struct mmc_host
> > *mmc,
> > > struct mmc_request *mrq)
> > >  #ifndef SDHCI_USE_LEDS_CLASS
> > >  	sdhci_activate_led(host);
> > >  #endif
> > > +	/*
> > > +	 * Since the block count for CMD23 has already been specified in
> > > the
> > > +	 * Argument 2 register, we don't need CMD12 to stop multiple
> > > block
> > > +	 * transfers.
> > > +	 */
> > > +	if (sdhci_host_auto_cmd23_supported(host, mrq)) {
> > > +		if (mrq->stop) {
> > > +			/*
> > > +			 * Save the stop command here to be used during
> > > +			 * error recovery
> > > +			 */
> > > +			host->saved_abort_cmd = mrq->data->stop;
> > > +			mrq->data->stop = NULL;
> > > +			mrq->stop = NULL;
> > > +		}
> > > +	}
> > > +
> > >  	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) {
> > >  		if (mrq->stop) {
> > >  			mrq->data->stop = NULL;
> > > @@ -1396,6 +1449,7 @@ static void sdhci_timeout_timer(unsigned long
> > > data)
> > >
> > >  		if (host->data) {
> > >  			host->data->error = -ETIMEDOUT;
> > > +			host->data->stop = host->saved_abort_cmd;
> > >  			sdhci_finish_data(host);
> > >  		} else {
> > >  			if (host->cmd)
> > > @@ -1534,9 +1588,10 @@ static void sdhci_data_irq(struct sdhci_host
> > > *host, u32 intmask)
> > >  		host->data->error = -EIO;
> > >  	}
> > >
> > > -	if (host->data->error)
> > > +	if (host->data->error) {
> > > +		host->data->stop = host->saved_abort_cmd;
> > >  		sdhci_finish_data(host);
> > > -	else {
> > > +	} else {
> > >  		if (intmask & (SDHCI_INT_DATA_AVAIL |
> > > SDHCI_INT_SPACE_AVAIL))
> > >  			sdhci_transfer_pio(host);
> > >
> > > @@ -1792,6 +1847,10 @@ int sdhci_add_host(struct sdhci_host *host)
> > >  		host->flags &= ~SDHCI_USE_ADMA;
> > >  	}
> > >
> > > +	/* If the host can perform ADMA operation, we reset SDMA flag */
> > > +	if (host->flags & SDHCI_USE_ADMA)
> > > +		host->flags &= ~SDHCI_USE_SDMA;
> > > +
> > >  	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
> > >  		if (host->ops->enable_dma) {
> > >  			if (host->ops->enable_dma(host)) {
> > > diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> > > index 6e0969e..223762c 100644
> > > --- a/drivers/mmc/host/sdhci.h
> > > +++ b/drivers/mmc/host/sdhci.h
> > > @@ -25,6 +25,7 @@
> > >   */
> > >
> > >  #define SDHCI_DMA_ADDRESS	0x00
> > > +#define SDHCI_ARGUMENT2		SDHCI_DMA_ADDRESS
> > >
> > >  #define SDHCI_BLOCK_SIZE	0x04
> > >  #define  SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) |
> (blksz
> > &
> > > 0xFFF))
> > > @@ -37,6 +38,7 @@
> > >  #define  SDHCI_TRNS_DMA		0x01
> > >  #define  SDHCI_TRNS_BLK_CNT_EN	0x02
> > >  #define  SDHCI_TRNS_ACMD12	0x04
> > > +#define  SDHCI_TRNS_AUTO_CMD23	0x08
> > >  #define  SDHCI_TRNS_READ	0x10
> > >  #define  SDHCI_TRNS_MULTI	0x20
> > >
> > > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> > > index 8ce0827..22b0335 100644
> > > --- a/include/linux/mmc/card.h
> > > +++ b/include/linux/mmc/card.h
> > > @@ -58,9 +58,13 @@ struct mmc_ext_csd {
> > >
> > >  struct sd_scr {
> > >  	unsigned char		sda_vsn;
> > > +	unsigned char		sda_spec3;
> > >  	unsigned char		bus_widths;
> > >  #define SD_SCR_BUS_WIDTH_1	(1<<0)
> > >  #define SD_SCR_BUS_WIDTH_4	(1<<2)
> > > +	unsigned char		cmd_support;
> > > +#define SD_SCR_CMD20_SUPPORT	(1<<0)
> > > +#define SD_SCR_CMD23_SUPPORT	(1<<1)
> > >  };
> > >
> > >  struct sd_ssr {
> > > diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
> > > index 3fd85e0..178363b 100644
> > > --- a/include/linux/mmc/sd.h
> > > +++ b/include/linux/mmc/sd.h
> > > @@ -59,7 +59,7 @@
> > >
> > >  #define SCR_SPEC_VER_0		0	/* Implements system
> > specification
> > > 1.0 - 1.01 */
> > >  #define SCR_SPEC_VER_1		1	/* Implements system
> > specification
> > > 1.10 */
> > > -#define SCR_SPEC_VER_2		2	/* Implements system
> > specification
> > > 2.00 */
> > > +#define SCR_SPEC_VER_2		2	/* Implements system
> > specification
> > > 2.00 - 3.0x */
> > >
> > >  /*
> > >   * SD bus widths
> > > diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
> > > index 83bd9f7..282d158 100644
> > > --- a/include/linux/mmc/sdhci.h
> > > +++ b/include/linux/mmc/sdhci.h
> > > @@ -145,6 +145,8 @@ struct sdhci_host {
> > >  	unsigned int            ocr_avail_sd;
> > >  	unsigned int            ocr_avail_mmc;
> > >
> > > +	struct mmc_command	*saved_abort_cmd; /* Abort command saved
> > > for data error recovery */
> > > +
> > >  	unsigned long private[0] ____cacheline_aligned;
> > >  };
> > >  #endif /* __SDHCI_H */
> > > --
> > > 1.7.1
> > >
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-
> mmc"
> > in
> > > the body of a message to majordomo@vger.kernel.org
> > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #3: Type: message/rfc822, Size: 11340 bytes --]

From: "Subhash Jadavani" <subhashj@codeaurora.org>
To: "'Arindam Nath'" <arindam.nath@amd.com>, <cjb@laptop.org>
Cc: <zhangfei.gao@gmail.com>, <prakity@marvell.com>, <linux-mmc@vger.kernel.org>, <henry.su@amd.com>, <aaron.lu@amd.com>, <anath.amd@gmail.com>
Subject: RE: [PATCH v2 01/12] mmc: sdhci: add support for auto CMD23
Date: Tue, 15 Mar 2011 16:53:39 +0530
Message-ID: <002301cbe303$714c1650$53e442f0$@org>

Arindam,

Capability to send CMD23 automatically is something specific to your
controller.
CMD23 (SET_BLOCK_COUNT) is a new command added in SD3.0 spec and mandatory
for SDR104 mode. Why are you not adding this command in core/block layer
before sending multi byte read command to host controller driver?

Regards,
Subhash

> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Arindam Nath
> Sent: Friday, March 04, 2011 5:03 PM
> To: cjb@laptop.org
> Cc: zhangfei.gao@gmail.com; prakity@marvell.com;
> subhashj@codeaurora.org; linux-mmc@vger.kernel.org; henry.su@amd.com;
> aaron.lu@amd.com; anath.amd@gmail.com; Arindam Nath
> Subject: [PATCH v2 01/12] mmc: sdhci: add support for auto CMD23
> 
> Host Controller v3.00 and later support Auto CMD23 in the Transfer
> Mode register. Since Auto CMD23 can be used with or without DMA,
> and if used with DMA, it should _only_ be ADMA, we check against
> SDHCI_USE_SDMA not being set. This flag is reset when SDHCI_USE_ADMA
> is set.
> 
> A new definition for SDHCI_ARGUMENT2 register has been added in v3.00
> spec, which is the same as SDHCI_DMA_ADDRESS. We program the block
> count for CMD23 in SDHCI_ARGUMENT2, so we don't need CMD12 to stop
> multiple block transfers. But during error recovery procedure, we will
> need to send Abort command, so we use a variable saved_abort_cmd to
> save the stop command to be used later.
> 
> Two bits are added to SCR register as per the Physical Layer Spec
> v3.01,
> which specify whether the card supports CMD20 and/or CMD23. We use this
> as one of the conditions to decide whether to enable Auto CMD23 or not.
> 
> Signed-off-by: Arindam Nath <arindam.nath@amd.com>
> ---
>  drivers/mmc/core/sd.c     |    6 ++++
>  drivers/mmc/host/sdhci.c  |   69
> +++++++++++++++++++++++++++++++++++++++++---
>  drivers/mmc/host/sdhci.h  |    2 +
>  include/linux/mmc/card.h  |    4 ++
>  include/linux/mmc/sd.h    |    2 +-
>  include/linux/mmc/sdhci.h |    2 +
>  6 files changed, 79 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index d18c32b..b3f8a3c 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -188,6 +188,12 @@ static int mmc_decode_scr(struct mmc_card *card)
> 
>  	scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
>  	scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
> +	if (scr->sda_vsn == SCR_SPEC_VER_2) {
> +		/* Check if Physical Layer Spec v3.0 is supported*/
> +		scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
> +		if (scr->sda_spec3)
> +			scr->cmd_support = UNSTUFF_BITS(resp, 32, 2);
> +	}
> 
>  	if (UNSTUFF_BITS(resp, 55, 1))
>  		card->erased_byte = 0xFF;
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 9e15f41..8914a25 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -25,6 +25,7 @@
> 
>  #include <linux/mmc/mmc.h>
>  #include <linux/mmc/host.h>
> +#include <linux/mmc/card.h>
> 
>  #include "sdhci.h"
> 
> @@ -812,6 +813,30 @@ static void sdhci_prepare_data(struct sdhci_host
> *host, struct mmc_data *data)
>  	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
>  }
> 
> +/*
> + * Does the Host Controller support Auto CMD23?
> + *
> + * There are four preconditions for Auto CMD23 to be supported:
> + *  1. Host Controller v3.00 or later
> + *  2. Card supports CMD23
> + *  3. If DMA is used, it should be ADMA
> + *  4. Only when CMD18 or CMD25 is issued
> + */
> +static int sdhci_host_auto_cmd23_supported(struct sdhci_host *host,
> +	struct mmc_request *mrq)
> +{
> +	struct mmc_card *card = host->mmc->card;
> +
> +	if ((host->version >= SDHCI_SPEC_300) &&
> +	   card && (card->scr.cmd_support & SD_SCR_CMD23_SUPPORT) &&
> +	   !(host->flags & SDHCI_USE_SDMA) &&
> +	   ((mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK) ||
> +	   (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK)))
> +		return 1;
> +
> +	return 0;
> +}
> +
>  static void sdhci_set_transfer_mode(struct sdhci_host *host,
>  	struct mmc_data *data)
>  {
> @@ -825,10 +850,21 @@ static void sdhci_set_transfer_mode(struct
> sdhci_host *host,
>  	mode = SDHCI_TRNS_BLK_CNT_EN;
>  	if (data->blocks > 1) {
>  		if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
> -			mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
> -		else
> -			mode |= SDHCI_TRNS_MULTI;
> +			mode |= SDHCI_TRNS_ACMD12;
> +		else if (sdhci_host_auto_cmd23_supported(host, host->mrq))
> {
> +			/*
> +			 * Host Controller v3.00 can automatically send
CMD23
> +			 * before CMD18 or CMD25. For that, we need to
enable
> +			 * Auto CMD23 in the Transfer Mode register and
> +			 * program the block count in Argument 2 register.
> +			 */
> +			mode |= SDHCI_TRNS_AUTO_CMD23;
> +			sdhci_writel(host, data->blocks, SDHCI_ARGUMENT2);
> +		}
> +
> +		mode |= SDHCI_TRNS_MULTI;
>  	}
> +
>  	if (data->flags & MMC_DATA_READ)
>  		mode |= SDHCI_TRNS_READ;
>  	if (host->flags & SDHCI_REQ_USE_DMA)
> @@ -1131,6 +1167,23 @@ static void sdhci_request(struct mmc_host *mmc,
> struct mmc_request *mrq)
>  #ifndef SDHCI_USE_LEDS_CLASS
>  	sdhci_activate_led(host);
>  #endif
> +	/*
> +	 * Since the block count for CMD23 has already been specified in
> the
> +	 * Argument 2 register, we don't need CMD12 to stop multiple
> block
> +	 * transfers.
> +	 */
> +	if (sdhci_host_auto_cmd23_supported(host, mrq)) {
> +		if (mrq->stop) {
> +			/*
> +			 * Save the stop command here to be used during
> +			 * error recovery
> +			 */
> +			host->saved_abort_cmd = mrq->data->stop;
> +			mrq->data->stop = NULL;
> +			mrq->stop = NULL;
> +		}
> +	}
> +
>  	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) {
>  		if (mrq->stop) {
>  			mrq->data->stop = NULL;
> @@ -1396,6 +1449,7 @@ static void sdhci_timeout_timer(unsigned long
> data)
> 
>  		if (host->data) {
>  			host->data->error = -ETIMEDOUT;
> +			host->data->stop = host->saved_abort_cmd;
>  			sdhci_finish_data(host);
>  		} else {
>  			if (host->cmd)
> @@ -1534,9 +1588,10 @@ static void sdhci_data_irq(struct sdhci_host
> *host, u32 intmask)
>  		host->data->error = -EIO;
>  	}
> 
> -	if (host->data->error)
> +	if (host->data->error) {
> +		host->data->stop = host->saved_abort_cmd;
>  		sdhci_finish_data(host);
> -	else {
> +	} else {
>  		if (intmask & (SDHCI_INT_DATA_AVAIL |
> SDHCI_INT_SPACE_AVAIL))
>  			sdhci_transfer_pio(host);
> 
> @@ -1792,6 +1847,10 @@ int sdhci_add_host(struct sdhci_host *host)
>  		host->flags &= ~SDHCI_USE_ADMA;
>  	}
> 
> +	/* If the host can perform ADMA operation, we reset SDMA flag */
> +	if (host->flags & SDHCI_USE_ADMA)
> +		host->flags &= ~SDHCI_USE_SDMA;
> +
>  	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
>  		if (host->ops->enable_dma) {
>  			if (host->ops->enable_dma(host)) {
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 6e0969e..223762c 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -25,6 +25,7 @@
>   */
> 
>  #define SDHCI_DMA_ADDRESS	0x00
> +#define SDHCI_ARGUMENT2		SDHCI_DMA_ADDRESS
> 
>  #define SDHCI_BLOCK_SIZE	0x04
>  #define  SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz &
> 0xFFF))
> @@ -37,6 +38,7 @@
>  #define  SDHCI_TRNS_DMA		0x01
>  #define  SDHCI_TRNS_BLK_CNT_EN	0x02
>  #define  SDHCI_TRNS_ACMD12	0x04
> +#define  SDHCI_TRNS_AUTO_CMD23	0x08
>  #define  SDHCI_TRNS_READ	0x10
>  #define  SDHCI_TRNS_MULTI	0x20
> 
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 8ce0827..22b0335 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -58,9 +58,13 @@ struct mmc_ext_csd {
> 
>  struct sd_scr {
>  	unsigned char		sda_vsn;
> +	unsigned char		sda_spec3;
>  	unsigned char		bus_widths;
>  #define SD_SCR_BUS_WIDTH_1	(1<<0)
>  #define SD_SCR_BUS_WIDTH_4	(1<<2)
> +	unsigned char		cmd_support;
> +#define SD_SCR_CMD20_SUPPORT	(1<<0)
> +#define SD_SCR_CMD23_SUPPORT	(1<<1)
>  };
> 
>  struct sd_ssr {
> diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
> index 3fd85e0..178363b 100644
> --- a/include/linux/mmc/sd.h
> +++ b/include/linux/mmc/sd.h
> @@ -59,7 +59,7 @@
> 
>  #define SCR_SPEC_VER_0		0	/* Implements system
specification
> 1.0 - 1.01 */
>  #define SCR_SPEC_VER_1		1	/* Implements system
specification
> 1.10 */
> -#define SCR_SPEC_VER_2		2	/* Implements system
specification
> 2.00 */
> +#define SCR_SPEC_VER_2		2	/* Implements system
specification
> 2.00 - 3.0x */
> 
>  /*
>   * SD bus widths
> diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
> index 83bd9f7..282d158 100644
> --- a/include/linux/mmc/sdhci.h
> +++ b/include/linux/mmc/sdhci.h
> @@ -145,6 +145,8 @@ struct sdhci_host {
>  	unsigned int            ocr_avail_sd;
>  	unsigned int            ocr_avail_mmc;
> 
> +	struct mmc_command	*saved_abort_cmd; /* Abort command saved
> for data error recovery */
> +
>  	unsigned long private[0] ____cacheline_aligned;
>  };
>  #endif /* __SDHCI_H */
> --
> 1.7.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" 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] 27+ messages in thread

* RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-16  6:17             ` Subhash Jadavani
@ 2011-04-16  6:25               ` Nath, Arindam
  2011-04-16  6:37                 ` Subhash Jadavani
  2011-04-16  8:17                 ` Andrei Warkentin
  0 siblings, 2 replies; 27+ messages in thread
From: Nath, Arindam @ 2011-04-16  6:25 UTC (permalink / raw)
  To: Subhash Jadavani, 'Andrei Warkentin', linux-mmc

Hi Subhash,


> -----Original Message-----
> From: Subhash Jadavani [mailto:subhashj@codeaurora.org]
> Sent: Saturday, April 16, 2011 11:47 AM
> To: 'Andrei Warkentin'; Nath, Arindam; linux-mmc@vger.kernel.org
> Subject: RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> 
> > -----Original Message-----
> > From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> > owner@vger.kernel.org] On Behalf Of Andrei Warkentin
> > Sent: Saturday, April 16, 2011 1:34 AM
> > To: Nath, Arindam; linux-mmc@vger.kernel.org
> > Subject: Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> >
> > +linux-mmc
> >
> > On Fri, Apr 15, 2011 at 3:03 PM, Andrei Warkentin
> > <andreiw@motorola.com> wrote:
> > > On Fri, Apr 15, 2011 at 1:57 PM, Andrei Warkentin
> > <andreiw@motorola.com> wrote:
> > >> Hi Arindam,
> > >>
> > >> On Fri, Apr 15, 2011 at 12:34 PM, Nath, Arindam
> > <Arindam.Nath@amd.com> wrote:
> > >>> Hi Andrei,
> > >>
> > >>>>
> > >>>> I've recently posted changes relating to CMD23 support in block
> > layer.
> > >>>> Effectively, in order to support hosts with and without
> > >>>> Auto-CMD23 (and with proper error handling) there is a new
> > >>>> MMC_CAP_CMD23 for
> > the
> > >>>> host, and a new field "mmc_command sbc" inside the mmc_request.
> > >>>>
> > >>>> I also have a patch enabling CMD23 use with an SDHCI host (<
> > 3.00).
> > >>>>
> > >>>> Could you be so kind as to rebase this patch on top of that?
> > You're
> > >>>> doing a lot of things here that you really shouldn't be (like
> > >>>> enforcing policy on what gets sent to cards, knowing what's
> > connected
> > >>>> to the host, conflicting with reliable writes code if Auto-CMD23
> > was
> > >>>> enabled for MMCs, not supporting MMCs which always have
> > >>>> SET_BLOCK_COUNT).
> > >>>
> > >>> Our Host Controller is complaint to the Host Controller Spec
> > >>> v3.00,
> > and since Auto CMD23 is a feature added to the HC, I thought it would
> > be better to make this feature part of sdhci and not the core/block
> > layer.
> > >>>
> > >>> But in case you want Auto CMD23 to be implemented in a different
> > way, it would rather be great if you help me implement in your own
> > way, and then probably based on community suggestions, we can keep
> > either of the patch.
> > >>
> > >> Let me clarify:
> > >>
> > >> 1) Sending CMD23 on multiblock transfers is not a an SDHCI
> specific
> > >> feature. It's a feature of MMC cards and SD cards operating at
> > UHS104
> > >> or greater.
> > >> 2) CMD23-bounded multi block writes are a generic problem already
> -
> > >> eMMC reliable writes, for example.
> > >> 3) CMD23 is not bound to any specific controller - so having
> > >> generic code to allow execution of CMD23 will speed up transfers
> > >> (and enable certain features) on any host.
> 
> These are the same point I had discussed earlier with Arindam. Please
> check the attached mails.
> 
> Yes, I would also agree with Andrei that all generic code related to
> CMD23 handling should be in core/block layer. Internally host
> controller driver can handle CMD23 differently as not all host
> controller support AUTO-CMD23.

Please keep in mind that my patch _only_ adds support for Auto CMD23, and not CMD23. CMD23 support can be made part of block layer, but Auto CMD23 is a feature as per the Host Controller Spec v3.00. So my patch takes care of the second case.

Thanks,
Arindam

> 
> > >> 4) Auto-CMD is a specific SDHCI enhancement, meant to reduce
> > overhead
> > >> of sending CMD23.
> > >> 5) Host controller has to be aware of CMD23 sending, because on an
> > >> error STOP has to be sent, and without error, no STOP has to be
> > sent.
> > >>
> > >> You are in a unique position where you have functional SDHCI 3.0
> > >> hardware and are able to test Auto-CMD23. Please look at the patch
> > set
> > >> I sent - it should be trivial to extend current SDHCI patch to use
> > >> Auto-CMD23 when possible instead of sending mmc_request->sbc.
> > >> Basically, I have a generic improvement that affects all host
> > >> controllers. Auto-CMD23 is an optimization of that for SDHCI 3.0.
> > >>
> > >> Your current patch to enable Auto-CMD23 is not useful as far as
> > >> non-
> > SD
> > >> cards are concerned and you push way to much policy and
> > >> non-host-related complexity into it.
> > >>
> > >> Thanks,
> > >> A
> > >>
> > >
> > > More clarification:
> > >
> > > The block layer patch may change slightly
> (whitelisting/blacklisting
> > > certain MMC devices for using CMD23 for multiblock transfers), but
> > the
> > > changes to mmc_request and SDHCI are not. So feel free to rebase it
> > > without waiting for anything. If you need help, I will gladly help
> > > you, but keep in mind I don't have SDHCI 3.0 hardware around.
> > >
> > > Thanks,
> > > A
> > >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-mmc"
> > 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] 27+ messages in thread

* RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-16  6:25               ` Nath, Arindam
@ 2011-04-16  6:37                 ` Subhash Jadavani
  2011-04-16  6:43                   ` Nath, Arindam
  2011-04-16  8:17                 ` Andrei Warkentin
  1 sibling, 1 reply; 27+ messages in thread
From: Subhash Jadavani @ 2011-04-16  6:37 UTC (permalink / raw)
  To: 'Nath, Arindam', 'Andrei Warkentin', linux-mmc



> -----Original Message-----
> From: Nath, Arindam [mailto:Arindam.Nath@amd.com]
> Sent: Saturday, April 16, 2011 11:56 AM
> To: Subhash Jadavani; 'Andrei Warkentin'; linux-mmc@vger.kernel.org
> Subject: RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> 
> Hi Subhash,
> 
> 
> > -----Original Message-----
> > From: Subhash Jadavani [mailto:subhashj@codeaurora.org]
> > Sent: Saturday, April 16, 2011 11:47 AM
> > To: 'Andrei Warkentin'; Nath, Arindam; linux-mmc@vger.kernel.org
> > Subject: RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> >
> > > -----Original Message-----
> > > From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> > > owner@vger.kernel.org] On Behalf Of Andrei Warkentin
> > > Sent: Saturday, April 16, 2011 1:34 AM
> > > To: Nath, Arindam; linux-mmc@vger.kernel.org
> > > Subject: Re: [PATCH v3 01/12] mmc: sdhci: add support for auto
> CMD23
> > >
> > > +linux-mmc
> > >
> > > On Fri, Apr 15, 2011 at 3:03 PM, Andrei Warkentin
> > > <andreiw@motorola.com> wrote:
> > > > On Fri, Apr 15, 2011 at 1:57 PM, Andrei Warkentin
> > > <andreiw@motorola.com> wrote:
> > > >> Hi Arindam,
> > > >>
> > > >> On Fri, Apr 15, 2011 at 12:34 PM, Nath, Arindam
> > > <Arindam.Nath@amd.com> wrote:
> > > >>> Hi Andrei,
> > > >>
> > > >>>>
> > > >>>> I've recently posted changes relating to CMD23 support in
> block
> > > layer.
> > > >>>> Effectively, in order to support hosts with and without
> > > >>>> Auto-CMD23 (and with proper error handling) there is a new
> > > >>>> MMC_CAP_CMD23 for
> > > the
> > > >>>> host, and a new field "mmc_command sbc" inside the
> mmc_request.
> > > >>>>
> > > >>>> I also have a patch enabling CMD23 use with an SDHCI host (<
> > > 3.00).
> > > >>>>
> > > >>>> Could you be so kind as to rebase this patch on top of that?
> > > You're
> > > >>>> doing a lot of things here that you really shouldn't be (like
> > > >>>> enforcing policy on what gets sent to cards, knowing what's
> > > connected
> > > >>>> to the host, conflicting with reliable writes code if Auto-
> CMD23
> > > was
> > > >>>> enabled for MMCs, not supporting MMCs which always have
> > > >>>> SET_BLOCK_COUNT).
> > > >>>
> > > >>> Our Host Controller is complaint to the Host Controller Spec
> > > >>> v3.00,
> > > and since Auto CMD23 is a feature added to the HC, I thought it
> would
> > > be better to make this feature part of sdhci and not the core/block
> > > layer.
> > > >>>
> > > >>> But in case you want Auto CMD23 to be implemented in a
> different
> > > way, it would rather be great if you help me implement in your own
> > > way, and then probably based on community suggestions, we can keep
> > > either of the patch.
> > > >>
> > > >> Let me clarify:
> > > >>
> > > >> 1) Sending CMD23 on multiblock transfers is not a an SDHCI
> > specific
> > > >> feature. It's a feature of MMC cards and SD cards operating at
> > > UHS104
> > > >> or greater.
> > > >> 2) CMD23-bounded multi block writes are a generic problem
> already
> > -
> > > >> eMMC reliable writes, for example.
> > > >> 3) CMD23 is not bound to any specific controller - so having
> > > >> generic code to allow execution of CMD23 will speed up transfers
> > > >> (and enable certain features) on any host.
> >
> > These are the same point I had discussed earlier with Arindam. Please
> > check the attached mails.
> >
> > Yes, I would also agree with Andrei that all generic code related to
> > CMD23 handling should be in core/block layer. Internally host
> > controller driver can handle CMD23 differently as not all host
> > controller support AUTO-CMD23.
> 
> Please keep in mind that my patch _only_ adds support for Auto CMD23,
> and not CMD23. CMD23 support can be made part of block layer, but Auto
> CMD23 is a feature as per the Host Controller Spec v3.00. So my patch
> takes care of the second case.

Agreed. But point is that Host controller driver should not be sending CMD23
to card unless indicated by core/block layer to do so. In your patch you are
checking in host controller driver that SD card supports CMD23 or not and
then sending the CMD23 for multi block read/write. MMC cards also supports
CMD23 so in that case again you have to check MMC EXT_CSD register for CMD23
support. All this logic is better be in core/block layer and let core/block
layer inform host controller when to send CMD23 and when not to.

> 
> Thanks,
> Arindam
> 
> >
> > > >> 4) Auto-CMD is a specific SDHCI enhancement, meant to reduce
> > > overhead
> > > >> of sending CMD23.
> > > >> 5) Host controller has to be aware of CMD23 sending, because on
> an
> > > >> error STOP has to be sent, and without error, no STOP has to be
> > > sent.
> > > >>
> > > >> You are in a unique position where you have functional SDHCI 3.0
> > > >> hardware and are able to test Auto-CMD23. Please look at the
> patch
> > > set
> > > >> I sent - it should be trivial to extend current SDHCI patch to
> use
> > > >> Auto-CMD23 when possible instead of sending mmc_request->sbc.
> > > >> Basically, I have a generic improvement that affects all host
> > > >> controllers. Auto-CMD23 is an optimization of that for SDHCI
> 3.0.
> > > >>
> > > >> Your current patch to enable Auto-CMD23 is not useful as far as
> > > >> non-
> > > SD
> > > >> cards are concerned and you push way to much policy and
> > > >> non-host-related complexity into it.
> > > >>
> > > >> Thanks,
> > > >> A
> > > >>
> > > >
> > > > More clarification:
> > > >
> > > > The block layer patch may change slightly
> > (whitelisting/blacklisting
> > > > certain MMC devices for using CMD23 for multiblock transfers),
> but
> > > the
> > > > changes to mmc_request and SDHCI are not. So feel free to rebase
> it
> > > > without waiting for anything. If you need help, I will gladly
> help
> > > > you, but keep in mind I don't have SDHCI 3.0 hardware around.
> > > >
> > > > Thanks,
> > > > A
> > > >
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-
> mmc"
> > > 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] 27+ messages in thread

* RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-16  6:37                 ` Subhash Jadavani
@ 2011-04-16  6:43                   ` Nath, Arindam
  2011-04-16  8:20                     ` Andrei Warkentin
  0 siblings, 1 reply; 27+ messages in thread
From: Nath, Arindam @ 2011-04-16  6:43 UTC (permalink / raw)
  To: Subhash Jadavani, 'Andrei Warkentin', linux-mmc

> -----Original Message-----
> From: Subhash Jadavani [mailto:subhashj@codeaurora.org]
> Sent: Saturday, April 16, 2011 12:07 PM
> To: Nath, Arindam; 'Andrei Warkentin'; linux-mmc@vger.kernel.org
> Subject: RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> 
> 
> 
> > -----Original Message-----
> > From: Nath, Arindam [mailto:Arindam.Nath@amd.com]
> > Sent: Saturday, April 16, 2011 11:56 AM
> > To: Subhash Jadavani; 'Andrei Warkentin'; linux-mmc@vger.kernel.org
> > Subject: RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> >
> > Hi Subhash,
> >
> >
> > > -----Original Message-----
> > > From: Subhash Jadavani [mailto:subhashj@codeaurora.org]
> > > Sent: Saturday, April 16, 2011 11:47 AM
> > > To: 'Andrei Warkentin'; Nath, Arindam; linux-mmc@vger.kernel.org
> > > Subject: RE: [PATCH v3 01/12] mmc: sdhci: add support for auto
> CMD23
> > >
> > > > -----Original Message-----
> > > > From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> > > > owner@vger.kernel.org] On Behalf Of Andrei Warkentin
> > > > Sent: Saturday, April 16, 2011 1:34 AM
> > > > To: Nath, Arindam; linux-mmc@vger.kernel.org
> > > > Subject: Re: [PATCH v3 01/12] mmc: sdhci: add support for auto
> > CMD23
> > > >
> > > > +linux-mmc
> > > >
> > > > On Fri, Apr 15, 2011 at 3:03 PM, Andrei Warkentin
> > > > <andreiw@motorola.com> wrote:
> > > > > On Fri, Apr 15, 2011 at 1:57 PM, Andrei Warkentin
> > > > <andreiw@motorola.com> wrote:
> > > > >> Hi Arindam,
> > > > >>
> > > > >> On Fri, Apr 15, 2011 at 12:34 PM, Nath, Arindam
> > > > <Arindam.Nath@amd.com> wrote:
> > > > >>> Hi Andrei,
> > > > >>
> > > > >>>>
> > > > >>>> I've recently posted changes relating to CMD23 support in
> > block
> > > > layer.
> > > > >>>> Effectively, in order to support hosts with and without
> > > > >>>> Auto-CMD23 (and with proper error handling) there is a new
> > > > >>>> MMC_CAP_CMD23 for
> > > > the
> > > > >>>> host, and a new field "mmc_command sbc" inside the
> > mmc_request.
> > > > >>>>
> > > > >>>> I also have a patch enabling CMD23 use with an SDHCI host (<
> > > > 3.00).
> > > > >>>>
> > > > >>>> Could you be so kind as to rebase this patch on top of that?
> > > > You're
> > > > >>>> doing a lot of things here that you really shouldn't be
> (like
> > > > >>>> enforcing policy on what gets sent to cards, knowing what's
> > > > connected
> > > > >>>> to the host, conflicting with reliable writes code if Auto-
> > CMD23
> > > > was
> > > > >>>> enabled for MMCs, not supporting MMCs which always have
> > > > >>>> SET_BLOCK_COUNT).
> > > > >>>
> > > > >>> Our Host Controller is complaint to the Host Controller Spec
> > > > >>> v3.00,
> > > > and since Auto CMD23 is a feature added to the HC, I thought it
> > would
> > > > be better to make this feature part of sdhci and not the
> core/block
> > > > layer.
> > > > >>>
> > > > >>> But in case you want Auto CMD23 to be implemented in a
> > different
> > > > way, it would rather be great if you help me implement in your
> own
> > > > way, and then probably based on community suggestions, we can
> keep
> > > > either of the patch.
> > > > >>
> > > > >> Let me clarify:
> > > > >>
> > > > >> 1) Sending CMD23 on multiblock transfers is not a an SDHCI
> > > specific
> > > > >> feature. It's a feature of MMC cards and SD cards operating at
> > > > UHS104
> > > > >> or greater.
> > > > >> 2) CMD23-bounded multi block writes are a generic problem
> > already
> > > -
> > > > >> eMMC reliable writes, for example.
> > > > >> 3) CMD23 is not bound to any specific controller - so having
> > > > >> generic code to allow execution of CMD23 will speed up
> transfers
> > > > >> (and enable certain features) on any host.
> > >
> > > These are the same point I had discussed earlier with Arindam.
> Please
> > > check the attached mails.
> > >
> > > Yes, I would also agree with Andrei that all generic code related
> to
> > > CMD23 handling should be in core/block layer. Internally host
> > > controller driver can handle CMD23 differently as not all host
> > > controller support AUTO-CMD23.
> >
> > Please keep in mind that my patch _only_ adds support for Auto CMD23,
> > and not CMD23. CMD23 support can be made part of block layer, but
> Auto
> > CMD23 is a feature as per the Host Controller Spec v3.00. So my patch
> > takes care of the second case.
> 
> Agreed. But point is that Host controller driver should not be sending
> CMD23
> to card unless indicated by core/block layer to do so. In your patch
> you are
> checking in host controller driver that SD card supports CMD23 or not
> and
> then sending the CMD23 for multi block read/write. MMC cards also
> supports
> CMD23 so in that case again you have to check MMC EXT_CSD register for
> CMD23

Yes, you are right. I followed the Physical Layer Spec v3.01 as is, so in case the support is needed for MMC cards, we will need to take care of that too.

> support. All this logic is better be in core/block layer and let
> core/block
> layer inform host controller when to send CMD23 and when not to.

Well in that case, Auto CMD23 will never make sense.

Thanks,
Arindam

> 
> >
> > Thanks,
> > Arindam
> >
> > >
> > > > >> 4) Auto-CMD is a specific SDHCI enhancement, meant to reduce
> > > > overhead
> > > > >> of sending CMD23.
> > > > >> 5) Host controller has to be aware of CMD23 sending, because
> on
> > an
> > > > >> error STOP has to be sent, and without error, no STOP has to
> be
> > > > sent.
> > > > >>
> > > > >> You are in a unique position where you have functional SDHCI
> 3.0
> > > > >> hardware and are able to test Auto-CMD23. Please look at the
> > patch
> > > > set
> > > > >> I sent - it should be trivial to extend current SDHCI patch to
> > use
> > > > >> Auto-CMD23 when possible instead of sending mmc_request->sbc.
> > > > >> Basically, I have a generic improvement that affects all host
> > > > >> controllers. Auto-CMD23 is an optimization of that for SDHCI
> > 3.0.
> > > > >>
> > > > >> Your current patch to enable Auto-CMD23 is not useful as far
> as
> > > > >> non-
> > > > SD
> > > > >> cards are concerned and you push way to much policy and
> > > > >> non-host-related complexity into it.
> > > > >>
> > > > >> Thanks,
> > > > >> A
> > > > >>
> > > > >
> > > > > More clarification:
> > > > >
> > > > > The block layer patch may change slightly
> > > (whitelisting/blacklisting
> > > > > certain MMC devices for using CMD23 for multiblock transfers),
> > but
> > > > the
> > > > > changes to mmc_request and SDHCI are not. So feel free to
> rebase
> > it
> > > > > without waiting for anything. If you need help, I will gladly
> > help
> > > > > you, but keep in mind I don't have SDHCI 3.0 hardware around.
> > > > >
> > > > > Thanks,
> > > > > A
> > > > >
> > > > --
> > > > To unsubscribe from this list: send the line "unsubscribe linux-
> > mmc"
> > > > 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] 27+ messages in thread

* Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-16  6:25               ` Nath, Arindam
  2011-04-16  6:37                 ` Subhash Jadavani
@ 2011-04-16  8:17                 ` Andrei Warkentin
  1 sibling, 0 replies; 27+ messages in thread
From: Andrei Warkentin @ 2011-04-16  8:17 UTC (permalink / raw)
  To: Nath, Arindam; +Cc: Subhash Jadavani, linux-mmc

On Sat, Apr 16, 2011 at 1:25 AM, Nath, Arindam <Arindam.Nath@amd.com> wrote:
> Hi Subhash,

> Please keep in mind that my patch _only_ adds support for Auto CMD23, and not CMD23. CMD23 support can be made part of block layer, but Auto CMD23 is a feature as per the Host Controller Spec v3.00. So my patch takes care of the second case.

All Auto CMD23 means is that the host sends the command automatically,
instead of having some code do it manually. Auto CMD23 makes no sense
if the block layer doesn't want or need CMD23. Let me explain:
1) Not all cards support CMD23
2) Not all cards that do support CMD23 want to use it for regular
multiblock transfers for performance reasons
3) If you disregard my current patch set, then your changes, if ever
enabled for MMCs, will actually break reliable writes because current
block code sent CMD23 manually (but the CMD23 support patch set fixed
that)

That means you can't just enable it in the host just because you feel
like it. Your current host changes make the host aware of the card
capabilities, and then force policy. This violates layering and makes
everything an unmaintainable mess.

Given the existing work for plumbing normal CMD23 support, you should
take advantage of that. Your current patch does not integrate well
with it, and I've tried to make it specifically very easy to enable
enhancements like Auto-CMD23. Let me help you out:

1) If you have mmc_request->sbc - then you should set your Auto-CMD23
flag and not send mmc_request->sbc.
2) You can forget your "save stop command". The current code should
function correctly as long as you can detect the error condition as
set data->error appropriately. But of course, feel
     free to change it if you see fit. Right now the stop command is
only sent if -
     a) No mmc_request->sbc so this must have been an open-ended
multiblock transfer
     b) An error condition detected in data transfer, so the stop must
be sent anyway

Anyway I'm at your disposal to answer your questions and make sure you
can implement AutoCMD23 support on top of existing MMC subsystem
changes.

A

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

* Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-16  6:43                   ` Nath, Arindam
@ 2011-04-16  8:20                     ` Andrei Warkentin
  0 siblings, 0 replies; 27+ messages in thread
From: Andrei Warkentin @ 2011-04-16  8:20 UTC (permalink / raw)
  To: Nath, Arindam; +Cc: Subhash Jadavani, linux-mmc

On Sat, Apr 16, 2011 at 1:43 AM, Nath, Arindam <Arindam.Nath@amd.com> wrote:
>> and
>> then sending the CMD23 for multi block read/write. MMC cards also
>> supports
>> CMD23 so in that case again you have to check MMC EXT_CSD register for
>> CMD23
>
> Yes, you are right. I followed the Physical Layer Spec v3.01 as is, so in case the support is needed for MMC cards, we will need to take care of that too.

It's already done. In the block layer. All you need to do is honor
mmc_request->sbc and set Auto-CMD23 and the CMD23 argument.

>> support. All this logic is better be in core/block layer and let
>> core/block
>> layer inform host controller when to send CMD23 and when not to.
>
> Well in that case, Auto CMD23 will never make sense.

I am unsure why you think that. All Auto CMD23 means is that instead
of manually sending CMD23 (and incurring the extra interrupt penalty),
I have the host automatically do it. But this feature should only be
enabled when upper layers care to enabled it. This is what the CMD23
support plumbed in.

A

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

* Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-16  5:25             ` Nath, Arindam
@ 2011-04-16  9:07               ` Andrei Warkentin
  2011-04-16  9:40                 ` Nath, Arindam
  0 siblings, 1 reply; 27+ messages in thread
From: Andrei Warkentin @ 2011-04-16  9:07 UTC (permalink / raw)
  To: Nath, Arindam; +Cc: linux-mmc

On Sat, Apr 16, 2011 at 12:25 AM, Nath, Arindam <Arindam.Nath@amd.com> wrote:
> Hi Andrei,
>
> I saw in one of the community threads that you also have a patch ready for supporting Auto CMD23 for SDHCI. Can you share the same with us? I would like to take a look at your patch first before deciding whether it would make sense for controllers which comply with Host Controller Spec v3.00.
>

Will send updated patch set in a few. You and Subhash are on the Cc.
Once again, the Auto-CMD23 is completely untested. I would be
extremely grateful if you can verify it.
Is there any kind of error injection mechanism you guys use to verify
the error paths for Auto 12/23?

By the way -

+       /* If the host can perform ADMA operation, we reset SDMA flag */
+       if (host->flags & SDHCI_USE_ADMA)
+               host->flags &= ~SDHCI_USE_SDMA;

This seems completely unnecessary, as the code already prefers ADMA to
SDMA. What do you think?

A

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

* RE: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-16  9:07               ` Andrei Warkentin
@ 2011-04-16  9:40                 ` Nath, Arindam
  2011-04-16 10:04                   ` Andrei Warkentin
  0 siblings, 1 reply; 27+ messages in thread
From: Nath, Arindam @ 2011-04-16  9:40 UTC (permalink / raw)
  To: Andrei Warkentin; +Cc: linux-mmc

Hi Andrei,


> -----Original Message-----
> From: Andrei Warkentin [mailto:andreiw@motorola.com]
> Sent: Saturday, April 16, 2011 2:38 PM
> To: Nath, Arindam
> Cc: linux-mmc@vger.kernel.org
> Subject: Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
> 
> On Sat, Apr 16, 2011 at 12:25 AM, Nath, Arindam <Arindam.Nath@amd.com>
> wrote:
> > Hi Andrei,
> >
> > I saw in one of the community threads that you also have a patch
> ready for supporting Auto CMD23 for SDHCI. Can you share the same with
> us? I would like to take a look at your patch first before deciding
> whether it would make sense for controllers which comply with Host
> Controller Spec v3.00.
> >
> 
> Will send updated patch set in a few. You and Subhash are on the Cc.
> Once again, the Auto-CMD23 is completely untested. I would be
> extremely grateful if you can verify it.

Yes, I can do that. On that note, I have a suggestion. Since the Auto CMD23 feature is separate and none of my other patches depend on this, I would rather re-submit V3 patches except for the Auto CMD23 feature. Then once your patches have been accepted and tested, we can enable Auto CMD23 feature in the kernel. Let me know what you think.

> Is there any kind of error injection mechanism you guys use to verify
> the error paths for Auto 12/23?

None in particular.

> 
> By the way -
> 
> +       /* If the host can perform ADMA operation, we reset SDMA flag
> */
> +       if (host->flags & SDHCI_USE_ADMA)
> +               host->flags &= ~SDHCI_USE_SDMA;
> 
> This seems completely unnecessary, as the code already prefers ADMA to
> SDMA. What do you think?

As per the Host Controller Spec v3.00, Auto CMD23 can either be used with non-DMA transfers or ADMA, but _not_ SDMA. To take care of both these cases in a single shot, I have tested against SDHCI_USE_SDMA not being set. So, I need to make sure we reset this flag when we enable ADMA support.

Thanks,
Arindam

> 
> A



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

* Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
  2011-04-16  9:40                 ` Nath, Arindam
@ 2011-04-16 10:04                   ` Andrei Warkentin
  0 siblings, 0 replies; 27+ messages in thread
From: Andrei Warkentin @ 2011-04-16 10:04 UTC (permalink / raw)
  To: Nath, Arindam; +Cc: linux-mmc

On Sat, Apr 16, 2011 at 4:40 AM, Nath, Arindam <Arindam.Nath@amd.com> wrote:
> Hi Andrei,
>
>
>> -----Original Message-----
>> From: Andrei Warkentin [mailto:andreiw@motorola.com]
>> Sent: Saturday, April 16, 2011 2:38 PM
>> To: Nath, Arindam
>> Cc: linux-mmc@vger.kernel.org
>> Subject: Re: [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23
>>
>> On Sat, Apr 16, 2011 at 12:25 AM, Nath, Arindam <Arindam.Nath@amd.com>
>> wrote:
>> > Hi Andrei,
>> >
>> > I saw in one of the community threads that you also have a patch
>> ready for supporting Auto CMD23 for SDHCI. Can you share the same with
>> us? I would like to take a look at your patch first before deciding
>> whether it would make sense for controllers which comply with Host
>> Controller Spec v3.00.
>> >
>>
>> Will send updated patch set in a few. You and Subhash are on the Cc.
>> Once again, the Auto-CMD23 is completely untested. I would be
>> extremely grateful if you can verify it.
>
> Yes, I can do that. On that note, I have a suggestion. Since the Auto CMD23 feature is separate and none of my other patches depend on this, I would rather re-submit V3 patches except for the Auto CMD23 feature. Then once your patches have been accepted and tested, we can enable Auto CMD23 feature in the kernel. Let me know what you think.

Sure, great! I've just mailed the v3 of my patch set, so I'm looking
forward to any comments you have and any problems you uncover with
Auto-CMD23.

>
>> Is there any kind of error injection mechanism you guys use to verify
>> the error paths for Auto 12/23?
>
> None in particular.
>

I am starting to wish I had a "fake" MMC or SD card I could program to
fail in various spectacular ways...

A

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

* RE: [PATCH v3 00/12] add support for host controller v3.00
  2011-04-15 14:06 ` [PATCH v3 00/12] add support for host controller v3.00 Chris Ball
  2011-04-15 14:06   ` Nath, Arindam
@ 2011-04-26  5:52   ` Nath, Arindam
  2011-04-26 12:50     ` Chris Ball
  1 sibling, 1 reply; 27+ messages in thread
From: Nath, Arindam @ 2011-04-26  5:52 UTC (permalink / raw)
  To: Chris Ball
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, Su, Henry, Lu, Aaron,
	anath.amd

Hi Chris,

> -----Original Message-----
> From: Chris Ball [mailto:cjb@laptop.org]
> Sent: Friday, April 15, 2011 7:36 PM
> To: Nath, Arindam
> Cc: linux-mmc@vger.kernel.org; subhashj@codeaurora.org;
> prakity@marvell.com; zhangfei.gao@gmail.com; Su, Henry; Lu, Aaron;
> anath.amd@gmail.com
> Subject: Re: [PATCH v3 00/12] add support for host controller v3.00
> 
> Hi Arindam,
> 
> On Fri, Apr 15 2011, Arindam Nath wrote:
> > V3
> 
> Thanks very much for reposting this!  I know it's a lot of work to keep
> track of so many comments and changes.
> 
> I've checked that this applies to mmc-next and doesn't add any compile
> warnings, and the patch quality (particularly your use of comments)
> looks excellent.  I'll wait a week for further comments and Tested-bys,
> and then look at whether we should push the series to mmc-next as-is
> or wait for another revision.

Just a follow up on what you said. Is there any plan to merge the patches with your tree?

Thanks,
Arindam

> 
> Thanks,
> 
> - Chris.
> --
> Chris Ball   <cjb@laptop.org>   <http://printf.net/>
> One Laptop Per Child



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

* Re: [PATCH v3 00/12] add support for host controller v3.00
  2011-04-26  5:52   ` Nath, Arindam
@ 2011-04-26 12:50     ` Chris Ball
  2011-04-26 13:02       ` Wolfram Sang
  2011-04-26 15:30       ` Philip Rakity
  0 siblings, 2 replies; 27+ messages in thread
From: Chris Ball @ 2011-04-26 12:50 UTC (permalink / raw)
  To: Nath, Arindam
  Cc: linux-mmc, subhashj, prakity, zhangfei.gao, Su, Henry, Lu, Aaron,
	anath.amd

Hi Arindam,

On Tue, Apr 26 2011, Nath, Arindam wrote:
> Just a follow up on what you said. Is there any plan to merge the
> patches with your tree?

Yes, sounds good -- linux-mmc@ folks, would anyone like to give a
Tested- or Reviewed-by: on these patches?

Thanks!

- Chris.
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

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

* Re: [PATCH v3 00/12] add support for host controller v3.00
  2011-04-26 12:50     ` Chris Ball
@ 2011-04-26 13:02       ` Wolfram Sang
  2011-04-26 13:19         ` Chris Ball
  2011-04-26 15:30       ` Philip Rakity
  1 sibling, 1 reply; 27+ messages in thread
From: Wolfram Sang @ 2011-04-26 13:02 UTC (permalink / raw)
  To: Chris Ball
  Cc: Nath, Arindam, linux-mmc, subhashj, prakity, zhangfei.gao, Su,
	Henry, Lu, Aaron, anath.amd

[-- Attachment #1: Type: text/plain, Size: 741 bytes --]

On Tue, Apr 26, 2011 at 08:50:31AM -0400, Chris Ball wrote:
> Hi Arindam,
> 
> On Tue, Apr 26 2011, Nath, Arindam wrote:
> > Just a follow up on what you said. Is there any plan to merge the
> > patches with your tree?
> 
> Yes, sounds good -- linux-mmc@ folks, would anyone like to give a
> Tested- or Reviewed-by: on these patches?

Considering this is a rather large changeset (thanks for doing it!),
what about putting it into an extra -next round (i.e. for-2.6.41) unless
somebody reviews or tests the series? I sadly can't, no hardware.

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH v3 00/12] add support for host controller v3.00
  2011-04-26 13:02       ` Wolfram Sang
@ 2011-04-26 13:19         ` Chris Ball
  0 siblings, 0 replies; 27+ messages in thread
From: Chris Ball @ 2011-04-26 13:19 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Nath, Arindam, linux-mmc, subhashj, prakity, zhangfei.gao, Su,
	Henry, Lu, Aaron, anath.amd

Hi Wolfram,

On Tue, Apr 26 2011, Wolfram Sang wrote:
> On Tue, Apr 26, 2011 at 08:50:31AM -0400, Chris Ball wrote:
>> Hi Arindam,
>> 
>> On Tue, Apr 26 2011, Nath, Arindam wrote:
>> Yes, sounds good -- linux-mmc@ folks, would anyone like to give a
>> Tested- or Reviewed-by: on these patches?
>
> Considering this is a rather large changeset (thanks for doing it!),
> what about putting it into an extra -next round (i.e. for-2.6.41) unless
> somebody reviews or tests the series? I sadly can't, no hardware.

I agree we should do this if we don't get reviewers or testers, but
I think we've already got several people testing this out -- I know
prakity has been following it and building a patchset on top of it
for eMMC, and we've had a huge number of review comments already.

So, I expect we'll pick up Tested-by tags and can plan on submitting
for .40 unless we start seeing regressions in mmc-next.

Thanks,

- Chris.
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

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

* Re: [PATCH v3 00/12] add support for host controller v3.00
  2011-04-26 12:50     ` Chris Ball
  2011-04-26 13:02       ` Wolfram Sang
@ 2011-04-26 15:30       ` Philip Rakity
  2011-04-26 15:41         ` Chris Ball
  1 sibling, 1 reply; 27+ messages in thread
From: Philip Rakity @ 2011-04-26 15:30 UTC (permalink / raw)
  To: Chris Ball
  Cc: Nath, Arindam, linux-mmc, subhashj, zhangfei.gao, Su, Henry, Lu,
	Aaron, anath.amd


Chris,

What is the format for this -- Can I add reviewed by as a note to all the patches or is this done one-by-one ?

I am using the code and have successfully run eMMC (DDR50) and SDIO (SDR50).  Patches for SDR50 will take me a while to finish but the code does work and is based on Arindam work.

Philip

On Apr 26, 2011, at 5:50 AM, Chris Ball wrote:

> Hi Arindam,
> 
> On Tue, Apr 26 2011, Nath, Arindam wrote:
>> Just a follow up on what you said. Is there any plan to merge the
>> patches with your tree?
> 
> Yes, sounds good -- linux-mmc@ folks, would anyone like to give a
> Tested- or Reviewed-by: on these patches?
> 
> Thanks!
> 
> - Chris.
> -- 
> Chris Ball   <cjb@laptop.org>   <http://printf.net/>
> One Laptop Per Child


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

* Re: [PATCH v3 00/12] add support for host controller v3.00
  2011-04-26 15:30       ` Philip Rakity
@ 2011-04-26 15:41         ` Chris Ball
  0 siblings, 0 replies; 27+ messages in thread
From: Chris Ball @ 2011-04-26 15:41 UTC (permalink / raw)
  To: Philip Rakity
  Cc: Nath, Arindam, linux-mmc, subhashj, zhangfei.gao, Su, Henry, Lu,
	Aaron, anath.amd

Hi,

On Tue, Apr 26 2011, Philip Rakity wrote:
> Chris,
>
> What is the format for this -- Can I add reviewed by as a note to all
> the patches or is this done one-by-one ?

Whichever you think is appropriate -- you can ask me to add your
Reviewed-by: to each patch and I'll do that, or you can reply to
specific ones if there's a large chunk of the patches that you
*haven't* looked at.

> I am using the code and have successfully run eMMC (DDR50) and SDIO
> (SDR50).  Patches for SDR50 will take me a while to finish but the
> code does work and is based on Arindam work.

Great, sounds like both Reviewed-by and Tested-by might be appropriate.

- Chris.
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

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

end of thread, other threads:[~2011-04-26 15:37 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-15 10:38 [PATCH v3 00/12] add support for host controller v3.00 Arindam Nath
2011-04-15 10:38 ` [PATCH v3 01/12] mmc: sdhci: add support for auto CMD23 Arindam Nath
     [not found]   ` <BANLkTimZGonC+D0czjiY4i7pFFW=upj_qw@mail.gmail.com>
     [not found]     ` <6C03668EAF45B747AF947A1603D1B300EB443FB6@SAUSEXMBP01.amd.com>
     [not found]       ` <BANLkTimEKQceSiuL=dX2yhMw+MLu7BzLvQ@mail.gmail.com>
     [not found]         ` <BANLkTimfQo7wJ3_ecs64VSp7xKJrjYdJ3w@mail.gmail.com>
2011-04-15 20:04           ` Andrei Warkentin
2011-04-16  5:25             ` Nath, Arindam
2011-04-16  9:07               ` Andrei Warkentin
2011-04-16  9:40                 ` Nath, Arindam
2011-04-16 10:04                   ` Andrei Warkentin
2011-04-16  6:17             ` Subhash Jadavani
2011-04-16  6:25               ` Nath, Arindam
2011-04-16  6:37                 ` Subhash Jadavani
2011-04-16  6:43                   ` Nath, Arindam
2011-04-16  8:20                     ` Andrei Warkentin
2011-04-16  8:17                 ` Andrei Warkentin
2011-04-15 10:38 ` [PATCH v3 02/12] mmc: sd: add support for signal voltage switch procedure Arindam Nath
2011-04-15 10:38 ` [PATCH v3 03/12] mmc: sd: query function modes for uhs cards Arindam Nath
2011-04-15 10:38 ` [PATCH v3 04/12] mmc: sd: add support for driver type selection Arindam Nath
2011-04-15 10:38 ` [PATCH v3 05/12] mmc: sdhci: reset sdclk before setting high speed enable Arindam Nath
2011-04-15 10:38 ` [PATCH v3 06/12] mmc: sd: add support for uhs bus speed mode selection Arindam Nath
2011-04-15 10:38 ` [PATCH v3 07/12] mmc: sd: set current limit for uhs cards Arindam Nath
2011-04-15 14:06 ` [PATCH v3 00/12] add support for host controller v3.00 Chris Ball
2011-04-15 14:06   ` Nath, Arindam
2011-04-26  5:52   ` Nath, Arindam
2011-04-26 12:50     ` Chris Ball
2011-04-26 13:02       ` Wolfram Sang
2011-04-26 13:19         ` Chris Ball
2011-04-26 15:30       ` Philip Rakity
2011-04-26 15:41         ` Chris Ball

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.