linux-mmc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arindam Nath <arindam.nath@amd.com>
To: cjb@laptop.org
Cc: prakity@marvell.com, zhangfei.gao@gmail.com,
	subhashj@codeaurora.org, linux-mmc@vger.kernel.org,
	henry.su@amd.com, aaron.lu@amd.com, anath.amd@gmail.com,
	Arindam Nath <arindam.nath@amd.com>
Subject: [PATCH v4 06/15] mmc: sd: set current limit for uhs cards
Date: Thu,  5 May 2011 12:19:02 +0530	[thread overview]
Message-ID: <1304578151-1775-7-git-send-email-arindam.nath@amd.com> (raw)
In-Reply-To: <1304578151-1775-1-git-send-email-arindam.nath@amd.com>

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>
Reviewed-by: Philip Rakity <prakity@marvell.com>
Tested-by: Philip Rakity <prakity@marvell.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 0491978..9270d82 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -517,6 +517,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
  */
@@ -555,6 +613,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 de7e6e9..9176911 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2217,6 +2217,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 4ef6ded..47b5ad3 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -105,6 +105,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 6237599..52b5dc9 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


  parent reply	other threads:[~2011-05-05  6:51 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-05  6:48 [PATCH v4 00/15] add support for host controller v3.00 Arindam Nath
2011-05-05  6:48 ` [PATCH v4 01/15] mmc: sd: add support for signal voltage switch procedure Arindam Nath
2011-05-06 10:36   ` zhangfei gao
2011-05-11  3:34   ` Chris Ball
2011-05-05  6:48 ` [PATCH v4 02/15] mmc: sd: query function modes for uhs cards Arindam Nath
2011-05-06 10:37   ` zhangfei gao
2011-05-11  3:34   ` Chris Ball
2011-05-05  6:48 ` [PATCH v4 03/15] mmc: sd: add support for driver type selection Arindam Nath
2011-05-06 10:37   ` zhangfei gao
2011-05-11  3:34   ` Chris Ball
2011-05-05  6:49 ` [PATCH v4 04/15] mmc: sdhci: reset sdclk before setting high speed enable Arindam Nath
2011-05-06 10:38   ` zhangfei gao
2011-05-11  3:36   ` Chris Ball
2011-05-05  6:49 ` [PATCH v4 05/15] mmc: sd: add support for uhs bus speed mode selection Arindam Nath
2011-05-06 10:41   ` zhangfei gao
2011-05-11  3:36   ` Chris Ball
2011-05-05  6:49 ` Arindam Nath [this message]
2011-05-06 10:38   ` [PATCH v4 06/15] mmc: sd: set current limit for uhs cards zhangfei gao
2011-05-11  3:37   ` Chris Ball
2011-05-05  6:49 ` [PATCH v4 07/15] mmc: sd: report correct speed and capacity of " Arindam Nath
2011-05-06 10:39   ` zhangfei gao
2011-05-11  3:37   ` Chris Ball
2011-05-05  6:49 ` [PATCH v4 08/15] mmc: sd: add support for tuning during uhs initialization Arindam Nath
2011-05-06 10:39   ` zhangfei gao
2011-05-11  3:38   ` Chris Ball
2011-05-05  6:49 ` [PATCH v4 09/15] mmc: sdhci: enable preset value after " Arindam Nath
2011-05-06 10:40   ` zhangfei gao
2011-05-11  3:38   ` Chris Ball
2011-05-05  6:49 ` [PATCH v4 10/15] mmc: sdhci: add support for programmable clock mode Arindam Nath
2011-05-06 10:40   ` zhangfei gao
2011-05-11  3:39   ` Chris Ball
2011-05-05  6:49 ` [PATCH v4 11/15] mmc: sdhci: add support for retuning mode 1 Arindam Nath
2011-05-06 10:40   ` zhangfei gao
2011-05-11  3:39   ` Chris Ball
2011-05-05  6:49 ` [PATCH v4 12/15] sdhci pxa add platform specific code for UHS signaling Arindam Nath
2011-05-11  1:54   ` Chris Ball
2011-05-11  8:48   ` zhangfei gao
2011-05-11  8:52     ` Philip Rakity
2011-05-11  9:28       ` zhangfei gao
2011-05-11  9:47         ` Philip Rakity
2011-05-12  1:53           ` Philip Rakity
2011-05-13  8:03           ` zhangfei gao
2011-05-15 21:42             ` Philip Rakity
2011-05-16  5:57               ` zhangfei gao
2011-05-05  6:49 ` [PATCH v4 13/15] mmc eMMC signal voltage does not use CMD11 Arindam Nath
2011-05-11  1:51   ` Chris Ball
2011-05-11  9:19   ` zhangfei gao
2011-05-11 15:01     ` Philip Rakity
2011-05-12  1:53       ` Philip Rakity
2011-05-05  6:49 ` [PATCH v4 14/15] sdhci add hooks for UHS setting by platform specific code Arindam Nath
2011-05-05  6:49 ` [PATCH v4 15/15] mmc add support for eMMC Dual Data Rate Arindam Nath
2011-05-05  8:18 ` [PATCH v4 00/15] add support for host controller v3.00 Nath, Arindam
2011-05-11  3:43 ` Chris Ball
2011-05-11  6:13   ` Nath, Arindam

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1304578151-1775-7-git-send-email-arindam.nath@amd.com \
    --to=arindam.nath@amd.com \
    --cc=aaron.lu@amd.com \
    --cc=anath.amd@gmail.com \
    --cc=cjb@laptop.org \
    --cc=henry.su@amd.com \
    --cc=linux-mmc@vger.kernel.org \
    --cc=prakity@marvell.com \
    --cc=subhashj@codeaurora.org \
    --cc=zhangfei.gao@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).