* [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode
@ 2013-01-28 14:08 Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 1/5] mmc: sd: Simplify by using mmc_host_uhs Johan Rudholm
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Johan Rudholm @ 2013-01-28 14:08 UTC (permalink / raw)
To: linux-mmc, Chris Ball
Cc: Per Forlin, Ulf Hansson, Fredrik Soderstedt, Kevin Liu,
Philip Rakity, Daniel Drake, Aaron, Subhash Jadavani,
Sujit Reddy Thumma, Wei WANG, Johan Rudholm
This patch series attempts to make the 1.8V signal voltage switch
required for UHS mode work according to the SD specification.
These patches have been tested with a couple of UHS SD cards, one of
which sometimes requires up to five power cycles before it accepts the
signal voltage switch. The patches have also been tested with various
other SD cards, as well as one SDIO WLAN chip (cw1200) to check
for regressions. The patches have also been tested with
CONFIG_MMC_CLKGATE.
As usual, I'd be very grateful if someone could help me test this patch
with an UHS SDIO card and perhaps also a combo card (which does seem to
be rare these days?)?
This patch series is based on previous RFC/patch:
[RFC/PATCH v2] mmc: core: Fixup signal voltage switch
and more recently on Kevin Liu's patches:
[PATCH v2 1/3] mmc: core: enhance the code for signal voltage setting
[PATCH v2 2/3] mmc: core: cycle power the card in voltage switch rather than mmc_sd_get_cid
Changelog:
v5 -> v6
- Rebase
- Adapt sd.c to use mmc_host_uhs introduced by
"mmc: sdio: Fix SDIO 3.0 UHS-I initialization sequence"
v4 -> v5
- Reset signal_voltage in struct ios if switch fails
v3 -> v4
- Added "mmc: core: Break out start_signal_voltage_switch",
which divides up mmc_set_signal_voltage to avoid a recursive
call from mmc_power_up. This removed the third argument
(cmd11) of the function
- Minor bug fixes
v2 -> v3
- Minor bug fixes
v1 -> v2
- Move mmc_power_cycle to the mmc_set_signal_voltage function
- Check card_busy before switching voltages
- Return -EPERM if signal voltage switch with cmd11 is
requested, but no start_signal_voltage_switch is defined.
- If we're switching back to 3.3 V, just do the switch without
checking card_busy etc
v2 -> This patch series
- Removed the extra argument to the card_busy host_ops function
- Added mmc_power_cycle
- Some clarifying comments
v1 -> v2
- Removed reset of signal voltage in mmc_sd_get_cid, since
"mmc: core: reset signal voltage on power up"
previous two patches -> v1:
- Keep calls to mmc_host_clk_hold / mmc_host_clk_release
- Add retry-loop / power cycle in sdio.c
- Fall back to 3.3 V if the switch repeatedly fails
- Add an extra argument to the card_busy host_ops function,
which can be used to signal polling use of the function
Johan Rudholm (5):
mmc: sd: Simplify by using mmc_host_uhs
mmc: core: Add mmc_power_cycle
mmc: core: Add card_busy to host_ops
mmc: core: Break out start_signal_voltage_switch
mmc: core: Fixup signal voltage switch
drivers/mmc/core/core.c | 114 +++++++++++++++++++++++++++++++++++++++-------
drivers/mmc/core/core.h | 5 +-
drivers/mmc/core/mmc.c | 8 ++--
drivers/mmc/core/sd.c | 27 +++++++----
drivers/mmc/core/sdio.c | 23 ++++++++--
include/linux/mmc/host.h | 3 ++
6 files changed, 145 insertions(+), 35 deletions(-)
--
1.7.10
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v6 1/5] mmc: sd: Simplify by using mmc_host_uhs
2013-01-28 14:08 [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Johan Rudholm
@ 2013-01-28 14:08 ` Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 2/5] mmc: core: Add mmc_power_cycle Johan Rudholm
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Johan Rudholm @ 2013-01-28 14:08 UTC (permalink / raw)
To: linux-mmc, Chris Ball
Cc: Per Forlin, Ulf Hansson, Fredrik Soderstedt, Kevin Liu,
Philip Rakity, Daniel Drake, Aaron, Subhash Jadavani,
Sujit Reddy Thumma, Wei WANG, Johan Rudholm
Signed-off-by: Johan Rudholm <johan.rudholm@stericsson.com>
---
drivers/mmc/core/sd.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 74972c2..9373639 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -444,8 +444,7 @@ static void sd_update_bus_speed_mode(struct mmc_card *card)
* 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))) {
+ if (!mmc_host_uhs(card->host)) {
card->sd_bus_speed = 0;
return;
}
@@ -736,8 +735,7 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
* 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))
+ if (mmc_host_uhs(host))
ocr |= SD_OCR_S18R;
/*
--
1.7.10
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 2/5] mmc: core: Add mmc_power_cycle
2013-01-28 14:08 [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 1/5] mmc: sd: Simplify by using mmc_host_uhs Johan Rudholm
@ 2013-01-28 14:08 ` Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 3/5] mmc: core: Add card_busy to host_ops Johan Rudholm
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Johan Rudholm @ 2013-01-28 14:08 UTC (permalink / raw)
To: linux-mmc, Chris Ball
Cc: Per Forlin, Ulf Hansson, Fredrik Soderstedt, Kevin Liu,
Philip Rakity, Daniel Drake, Aaron, Subhash Jadavani,
Sujit Reddy Thumma, Wei WANG, Johan Rudholm
Add mmc_power_cycle which can be used to power cycle for instance
SD-cards.
Signed-off-by: Johan Rudholm <johan.rudholm@stericsson.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Wei WANG <wei_wang@realsil.com.cn>
---
drivers/mmc/core/core.c | 8 ++++++++
drivers/mmc/core/core.h | 1 +
2 files changed, 9 insertions(+)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8b3a122..304c97c 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1470,6 +1470,14 @@ void mmc_power_off(struct mmc_host *host)
mmc_host_clk_release(host);
}
+void mmc_power_cycle(struct mmc_host *host)
+{
+ mmc_power_off(host);
+ /* Wait at least 1 ms according to SD spec */
+ mmc_delay(1);
+ mmc_power_up(host);
+}
+
/*
* Cleanup when the last reference to the bus operator is dropped.
*/
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 0272b32..9007de7 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -45,6 +45,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
void mmc_power_off(struct mmc_host *host);
+void mmc_power_cycle(struct mmc_host *host);
static inline void mmc_delay(unsigned int ms)
{
--
1.7.10
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 3/5] mmc: core: Add card_busy to host_ops
2013-01-28 14:08 [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 1/5] mmc: sd: Simplify by using mmc_host_uhs Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 2/5] mmc: core: Add mmc_power_cycle Johan Rudholm
@ 2013-01-28 14:08 ` Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 4/5] mmc: core: Break out start_signal_voltage_switch Johan Rudholm
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Johan Rudholm @ 2013-01-28 14:08 UTC (permalink / raw)
To: linux-mmc, Chris Ball
Cc: Per Forlin, Ulf Hansson, Fredrik Soderstedt, Kevin Liu,
Philip Rakity, Daniel Drake, Aaron, Subhash Jadavani,
Sujit Reddy Thumma, Wei WANG, Johan Rudholm
This host_ops member is used to test if the card is signaling busy by
pulling dat[0:3] low.
Signed-off-by: Johan Rudholm <johan.rudholm@stericsson.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Wei WANG <wei_wang@realsil.com.cn>
---
include/linux/mmc/host.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 523d570..0373b0a 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -131,6 +131,9 @@ struct mmc_host_ops {
int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
+ /* Check if the card is pulling dat[0:3] low */
+ int (*card_busy)(struct mmc_host *host);
+
/* The tuning command opcode value is different for SD and eMMC cards */
int (*execute_tuning)(struct mmc_host *host, u32 opcode);
void (*enable_preset_value)(struct mmc_host *host, bool enable);
--
1.7.10
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 4/5] mmc: core: Break out start_signal_voltage_switch
2013-01-28 14:08 [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Johan Rudholm
` (2 preceding siblings ...)
2013-01-28 14:08 ` [PATCH v6 3/5] mmc: core: Add card_busy to host_ops Johan Rudholm
@ 2013-01-28 14:08 ` Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 5/5] mmc: core: Fixup signal voltage switch Johan Rudholm
2013-02-11 16:21 ` [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Chris Ball
5 siblings, 0 replies; 11+ messages in thread
From: Johan Rudholm @ 2013-01-28 14:08 UTC (permalink / raw)
To: linux-mmc, Chris Ball
Cc: Per Forlin, Ulf Hansson, Fredrik Soderstedt, Kevin Liu,
Philip Rakity, Daniel Drake, Aaron, Subhash Jadavani,
Sujit Reddy Thumma, Wei WANG, Johan Rudholm
Allow callers to access the start_signal_voltage_switch host_ops
member without going through any cmd11 logic. This is mostly a
preparation for the following signal voltage switch patch.
Also, reset ios.signal_voltage to its original value if
start_signal_voltage_switch fails.
Signed-off-by: Johan Rudholm <johan.rudholm@stericsson.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Wei WANG <wei_wang@realsil.com.cn>
---
drivers/mmc/core/core.c | 35 +++++++++++++++++++++++------------
drivers/mmc/core/core.h | 4 ++--
drivers/mmc/core/mmc.c | 8 ++++----
drivers/mmc/core/sd.c | 2 +-
drivers/mmc/core/sdio.c | 3 +--
5 files changed, 31 insertions(+), 21 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 304c97c..3823351 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1317,7 +1317,26 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
return ocr;
}
-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11)
+int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
+{
+ int err = 0;
+ int old_signal_voltage = host->ios.signal_voltage;
+
+ host->ios.signal_voltage = signal_voltage;
+ if (host->ops->start_signal_voltage_switch) {
+ mmc_host_clk_hold(host);
+ err = host->ops->start_signal_voltage_switch(host, &host->ios);
+ mmc_host_clk_release(host);
+ }
+
+ if (err)
+ host->ios.signal_voltage = old_signal_voltage;
+
+ return err;
+
+}
+
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
{
struct mmc_command cmd = {0};
int err = 0;
@@ -1328,7 +1347,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11
* Send CMD11 only if the request is to switch the card to
* 1.8V signalling.
*/
- if ((signal_voltage != MMC_SIGNAL_VOLTAGE_330) && cmd11) {
+ if (signal_voltage != MMC_SIGNAL_VOLTAGE_330) {
cmd.opcode = SD_SWITCH_VOLTAGE;
cmd.arg = 0;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
@@ -1341,15 +1360,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11
return -EIO;
}
- host->ios.signal_voltage = signal_voltage;
-
- if (host->ops->start_signal_voltage_switch) {
- mmc_host_clk_hold(host);
- err = host->ops->start_signal_voltage_switch(host, &host->ios);
- mmc_host_clk_release(host);
- }
-
- return err;
+ return __mmc_set_signal_voltage(host, signal_voltage);
}
/*
@@ -1412,7 +1423,7 @@ static void mmc_power_up(struct mmc_host *host)
mmc_set_ios(host);
/* Set signal voltage to 3.3V */
- mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, false);
+ __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330);
/*
* This delay should be sufficient to allow the power supply
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 9007de7..b9f18a2 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -40,8 +40,8 @@ void mmc_set_ungated(struct mmc_host *host);
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
- bool cmd11);
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
+int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
void mmc_power_off(struct mmc_host *host);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index e6e3911..bd86771 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -769,11 +769,11 @@ static int mmc_select_hs200(struct mmc_card *card)
if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V &&
host->caps2 & MMC_CAP2_HS200_1_2V_SDR)
- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0);
+ err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
if (err && card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_8V &&
host->caps2 & MMC_CAP2_HS200_1_8V_SDR)
- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, 0);
+ err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
/* If fails try again during next card power cycle */
if (err)
@@ -1221,8 +1221,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
* WARNING: eMMC rules are NOT the same as SD DDR
*/
if (ddr == MMC_1_2V_DDR_MODE) {
- err = mmc_set_signal_voltage(host,
- MMC_SIGNAL_VOLTAGE_120, 0);
+ err = __mmc_set_signal_voltage(host,
+ MMC_SIGNAL_VOLTAGE_120);
if (err)
goto err;
}
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 9373639..9a59fcd 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -757,7 +757,7 @@ try_again:
*/
if (!mmc_host_is_spi(host) && rocr &&
((*rocr & 0x41000000) == 0x41000000)) {
- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true);
+ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
if (err) {
ocr &= ~SD_OCR_S18R;
goto try_again;
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 3a64933..1a726ae 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -647,8 +647,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
* it.
*/
if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
- true);
+ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
if (err) {
ocr &= ~R4_18V_PRESENT;
host->ocr &= ~R4_18V_PRESENT;
--
1.7.10
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 5/5] mmc: core: Fixup signal voltage switch
2013-01-28 14:08 [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Johan Rudholm
` (3 preceding siblings ...)
2013-01-28 14:08 ` [PATCH v6 4/5] mmc: core: Break out start_signal_voltage_switch Johan Rudholm
@ 2013-01-28 14:08 ` Johan Rudholm
2013-02-11 16:21 ` [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Chris Ball
5 siblings, 0 replies; 11+ messages in thread
From: Johan Rudholm @ 2013-01-28 14:08 UTC (permalink / raw)
To: linux-mmc, Chris Ball
Cc: Per Forlin, Ulf Hansson, Fredrik Soderstedt, Kevin Liu,
Philip Rakity, Daniel Drake, Aaron, Subhash Jadavani,
Sujit Reddy Thumma, Wei WANG, Johan Rudholm, Kevin Liu
When switching SD and SDIO cards from 3.3V to 1.8V signal levels, the
clock should be gated for 5 ms during the step. After enabling the
clock, the host should wait for at least 1 ms before checking for
failure. Failure by the card to switch is indicated by dat[0:3] being
pulled low. The host should check for this condition and power-cycle
the card if failure is indicated.
Add a retry mechanism for the SDIO case.
If the voltage switch fails repeatedly, give up and continue the
initialization using the original voltage.
This patch places a couple of requirements on the host driver:
1) mmc_set_ios with ios.clock = 0 must gate the clock
2) mmc_power_off must actually cut the power to the card
3) The card_busy host_ops member must be implemented
if these requirements are not fulfilled, the 1.8V signal voltage switch
will still be attempted but may not be successful.
Signed-off-by: Johan Rudholm <johan.rudholm@stericsson.com>
Signed-off-by: Kevin Liu <kliu5@marvell.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Wei WANG <wei_wang@realsil.com.cn>
---
drivers/mmc/core/core.c | 83 +++++++++++++++++++++++++++++++++++++++++------
drivers/mmc/core/sd.c | 21 +++++++++---
drivers/mmc/core/sdio.c | 20 ++++++++++--
3 files changed, 107 insertions(+), 17 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 3823351..2aee757 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1340,6 +1340,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
{
struct mmc_command cmd = {0};
int err = 0;
+ u32 clock;
BUG_ON(!host);
@@ -1347,20 +1348,82 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
* Send CMD11 only if the request is to switch the card to
* 1.8V signalling.
*/
- if (signal_voltage != MMC_SIGNAL_VOLTAGE_330) {
- cmd.opcode = SD_SWITCH_VOLTAGE;
- cmd.arg = 0;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+ if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+ return __mmc_set_signal_voltage(host, signal_voltage);
- err = mmc_wait_for_cmd(host, &cmd, 0);
- if (err)
- return err;
+ /*
+ * If we cannot switch voltages, return failure so the caller
+ * can continue without UHS mode
+ */
+ if (!host->ops->start_signal_voltage_switch)
+ return -EPERM;
+ if (!host->ops->card_busy)
+ pr_warning("%s: cannot verify signal voltage switch\n",
+ mmc_hostname(host));
+
+ 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;
+ if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
+ return -EIO;
+
+ mmc_host_clk_hold(host);
+ /*
+ * The card should drive cmd and dat[0:3] low immediately
+ * after the response of cmd11, but wait 1 ms to be sure
+ */
+ mmc_delay(1);
+ if (host->ops->card_busy && !host->ops->card_busy(host)) {
+ err = -EAGAIN;
+ goto power_cycle;
}
+ /*
+ * During a signal voltage level switch, the clock must be gated
+ * for 5 ms according to the SD spec
+ */
+ clock = host->ios.clock;
+ host->ios.clock = 0;
+ mmc_set_ios(host);
- return __mmc_set_signal_voltage(host, signal_voltage);
+ if (__mmc_set_signal_voltage(host, signal_voltage)) {
+ /*
+ * Voltages may not have been switched, but we've already
+ * sent CMD11, so a power cycle is required anyway
+ */
+ err = -EAGAIN;
+ goto power_cycle;
+ }
+
+ /* Keep clock gated for at least 5 ms */
+ mmc_delay(5);
+ host->ios.clock = clock;
+ mmc_set_ios(host);
+
+ /* Wait for at least 1 ms according to spec */
+ mmc_delay(1);
+
+ /*
+ * Failure to switch is indicated by the card holding
+ * dat[0:3] low
+ */
+ if (host->ops->card_busy && host->ops->card_busy(host))
+ err = -EAGAIN;
+
+power_cycle:
+ if (err) {
+ pr_debug("%s: Signal voltage switch failed, "
+ "power cycling card\n", mmc_hostname(host));
+ mmc_power_cycle(host);
+ }
+
+ mmc_host_clk_release(host);
+
+ return err;
}
/*
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 9a59fcd..03134b1 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -712,6 +712,14 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
{
int err;
u32 max_current;
+ int retries = 10;
+
+try_again:
+ if (!retries) {
+ ocr &= ~SD_OCR_S18R;
+ pr_warning("%s: Skipping voltage switch\n",
+ mmc_hostname(host));
+ }
/*
* Since we're changing the OCR value, we seem to
@@ -733,9 +741,10 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
/*
* If the host supports one of UHS-I modes, request the card
- * to switch to 1.8V signaling level.
+ * to switch to 1.8V signaling level. If the card has failed
+ * repeatedly to switch however, skip this.
*/
- if (mmc_host_uhs(host))
+ if (retries && mmc_host_uhs(host))
ocr |= SD_OCR_S18R;
/*
@@ -746,7 +755,6 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
if (max_current > 150)
ocr |= SD_OCR_XPC;
-try_again:
err = mmc_send_app_op_cond(host, ocr, rocr);
if (err)
return err;
@@ -758,8 +766,11 @@ try_again:
if (!mmc_host_is_spi(host) && rocr &&
((*rocr & 0x41000000) == 0x41000000)) {
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
- if (err) {
- ocr &= ~SD_OCR_S18R;
+ if (err == -EAGAIN) {
+ retries--;
+ goto try_again;
+ } else if (err) {
+ retries = 0;
goto try_again;
}
}
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 1a726ae..aa0719a 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -584,10 +584,19 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
{
struct mmc_card *card;
int err;
+ int retries = 10;
BUG_ON(!host);
WARN_ON(!host->claimed);
+try_again:
+ if (!retries) {
+ pr_warning("%s: Skipping voltage switch\n",
+ mmc_hostname(host));
+ ocr &= ~R4_18V_PRESENT;
+ host->ocr &= ~R4_18V_PRESENT;
+ }
+
/*
* Inform the card of the voltage
*/
@@ -646,9 +655,16 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
* systems that claim 1.8v signalling in fact do not support
* it.
*/
- if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
+ if (!powered_resume && (ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
- if (err) {
+ if (err == -EAGAIN) {
+ sdio_reset(host);
+ mmc_go_idle(host);
+ mmc_send_if_cond(host, host->ocr_avail);
+ mmc_remove_card(card);
+ retries--;
+ goto try_again;
+ } else if (err) {
ocr &= ~R4_18V_PRESENT;
host->ocr &= ~R4_18V_PRESENT;
}
--
1.7.10
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode
[not found] <25B60CDC2F704E4E9D88FFD52780CB4C08B059D33F@SC-VEXCH1.marvell.com>
@ 2013-01-29 4:32 ` Kevin Liu
2013-02-08 8:58 ` Ulf Hansson
0 siblings, 1 reply; 11+ messages in thread
From: Kevin Liu @ 2013-01-29 4:32 UTC (permalink / raw)
To: linux-mmc, Chris Ball, Johan Rudholm
Cc: Per Forlin, Ulf Hansson, Fredrik Soderstedt, Philip Rakity,
Daniel Drake, Aaron, Subhash Jadavani, Sujit Reddy Thumma,
Wei WANG
> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-owner@vger.kernel.org] On Behalf Of Johan Rudholm
> Sent: Monday, January 28, 2013 10:08 PM
> To: linux-mmc@vger.kernel.org; Chris Ball
> Cc: Per Forlin; Ulf Hansson; Fredrik Soderstedt; Kevin Liu; Philip Rakity; Daniel Drake; Aaron; Subhash Jadavani; Sujit Reddy Thumma; Wei WANG; Johan Rudholm
> Subject: [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode
>
> This patch series attempts to make the 1.8V signal voltage switch
> required for UHS mode work according to the SD specification.
>
> These patches have been tested with a couple of UHS SD cards, one of
> which sometimes requires up to five power cycles before it accepts the
> signal voltage switch. The patches have also been tested with various
> other SD cards, as well as one SDIO WLAN chip (cw1200) to check
> for regressions. The patches have also been tested with
> CONFIG_MMC_CLKGATE.
>
> As usual, I'd be very grateful if someone could help me test this patch
> with an UHS SDIO card and perhaps also a combo card (which does seem to
> be rare these days?)?
>
> This patch series is based on previous RFC/patch:
>
> [RFC/PATCH v2] mmc: core: Fixup signal voltage switch
>
> and more recently on Kevin Liu's patches:
>
> [PATCH v2 1/3] mmc: core: enhance the code for signal voltage setting
> [PATCH v2 2/3] mmc: core: cycle power the card in voltage switch rather than mmc_sd_get_cid
>
> Changelog:
> v5 -> v6
> - Rebase
> - Adapt sd.c to use mmc_host_uhs introduced by
> "mmc: sdio: Fix SDIO 3.0 UHS-I initialization sequence"
> v4 -> v5
> - Reset signal_voltage in struct ios if switch fails
> v3 -> v4
> - Added "mmc: core: Break out start_signal_voltage_switch",
> which divides up mmc_set_signal_voltage to avoid a recursive
> call from mmc_power_up. This removed the third argument
> (cmd11) of the function
> - Minor bug fixes
> v2 -> v3
> - Minor bug fixes
> v1 -> v2
> - Move mmc_power_cycle to the mmc_set_signal_voltage function
> - Check card_busy before switching voltages
> - Return -EPERM if signal voltage switch with cmd11 is
> requested, but no start_signal_voltage_switch is defined.
> - If we're switching back to 3.3 V, just do the switch without
> checking card_busy etc
> v2 -> This patch series
> - Removed the extra argument to the card_busy host_ops function
> - Added mmc_power_cycle
> - Some clarifying comments
> v1 -> v2
> - Removed reset of signal voltage in mmc_sd_get_cid, since
> "mmc: core: reset signal voltage on power up"
> previous two patches -> v1:
> - Keep calls to mmc_host_clk_hold / mmc_host_clk_release
> - Add retry-loop / power cycle in sdio.c
> - Fall back to 3.3 V if the switch repeatedly fails
> - Add an extra argument to the card_busy host_ops function,
> which can be used to signal polling use of the function
>
> Johan Rudholm (5):
> mmc: sd: Simplify by using mmc_host_uhs
> mmc: core: Add mmc_power_cycle
> mmc: core: Add card_busy to host_ops
> mmc: core: Break out start_signal_voltage_switch
> mmc: core: Fixup signal voltage switch
>
> drivers/mmc/core/core.c | 114 +++++++++++++++++++++++++++++++++++++++-------
> drivers/mmc/core/core.h | 5 +-
> drivers/mmc/core/mmc.c | 8 ++--
> drivers/mmc/core/sd.c | 27 +++++++----
> drivers/mmc/core/sdio.c | 23 ++++++++--
> include/linux/mmc/host.h | 3 ++
> 6 files changed, 145 insertions(+), 35 deletions(-)
>
>
Tested-by: Kevin Liu <kliu5@marvell.com>
Tested with both high speed and UHS sd cards.
Tested with emmc chip.
Tested with sdio card (non UHS).
Tested all the patchset together with below patch (update sdhci.c
accordingly) on sdhci-pxav3 platforms.
>From fc6069b79203f64e7efa8dd0bb295bebcd22f710 Mon Sep 17 00:00:00 2001
From: Kevin Liu <kliu5@marvell.com>
Date: Fri, 14 Dec 2012 16:44:10 +0800
Subject: [PATCH v3 3/3] mmc: sdhci: update signal voltage switch code
The protocal related code is moved to core stack. So update the host
driver accordingly.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode
2013-01-29 4:32 ` Kevin Liu
@ 2013-02-08 8:58 ` Ulf Hansson
0 siblings, 0 replies; 11+ messages in thread
From: Ulf Hansson @ 2013-02-08 8:58 UTC (permalink / raw)
To: Kevin Liu
Cc: linux-mmc, Chris Ball, Johan Rudholm, Per Forlin,
Fredrik Soderstedt, Philip Rakity, Daniel Drake, Aaron,
Subhash Jadavani, Sujit Reddy Thumma, Wei WANG
On 29 January 2013 05:32, Kevin Liu <keyuan.liu@gmail.com> wrote:
>> -----Original Message-----
>> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-owner@vger.kernel.org] On Behalf Of Johan Rudholm
>> Sent: Monday, January 28, 2013 10:08 PM
>> To: linux-mmc@vger.kernel.org; Chris Ball
>> Cc: Per Forlin; Ulf Hansson; Fredrik Soderstedt; Kevin Liu; Philip Rakity; Daniel Drake; Aaron; Subhash Jadavani; Sujit Reddy Thumma; Wei WANG; Johan Rudholm
>> Subject: [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode
>>
>> This patch series attempts to make the 1.8V signal voltage switch
>> required for UHS mode work according to the SD specification.
>>
>> These patches have been tested with a couple of UHS SD cards, one of
>> which sometimes requires up to five power cycles before it accepts the
>> signal voltage switch. The patches have also been tested with various
>> other SD cards, as well as one SDIO WLAN chip (cw1200) to check
>> for regressions. The patches have also been tested with
>> CONFIG_MMC_CLKGATE.
>>
>> As usual, I'd be very grateful if someone could help me test this patch
>> with an UHS SDIO card and perhaps also a combo card (which does seem to
>> be rare these days?)?
>>
>> This patch series is based on previous RFC/patch:
>>
>> [RFC/PATCH v2] mmc: core: Fixup signal voltage switch
>>
>> and more recently on Kevin Liu's patches:
>>
>> [PATCH v2 1/3] mmc: core: enhance the code for signal voltage setting
>> [PATCH v2 2/3] mmc: core: cycle power the card in voltage switch rather than mmc_sd_get_cid
>>
>> Changelog:
>> v5 -> v6
>> - Rebase
>> - Adapt sd.c to use mmc_host_uhs introduced by
>> "mmc: sdio: Fix SDIO 3.0 UHS-I initialization sequence"
>> v4 -> v5
>> - Reset signal_voltage in struct ios if switch fails
>> v3 -> v4
>> - Added "mmc: core: Break out start_signal_voltage_switch",
>> which divides up mmc_set_signal_voltage to avoid a recursive
>> call from mmc_power_up. This removed the third argument
>> (cmd11) of the function
>> - Minor bug fixes
>> v2 -> v3
>> - Minor bug fixes
>> v1 -> v2
>> - Move mmc_power_cycle to the mmc_set_signal_voltage function
>> - Check card_busy before switching voltages
>> - Return -EPERM if signal voltage switch with cmd11 is
>> requested, but no start_signal_voltage_switch is defined.
>> - If we're switching back to 3.3 V, just do the switch without
>> checking card_busy etc
>> v2 -> This patch series
>> - Removed the extra argument to the card_busy host_ops function
>> - Added mmc_power_cycle
>> - Some clarifying comments
>> v1 -> v2
>> - Removed reset of signal voltage in mmc_sd_get_cid, since
>> "mmc: core: reset signal voltage on power up"
>> previous two patches -> v1:
>> - Keep calls to mmc_host_clk_hold / mmc_host_clk_release
>> - Add retry-loop / power cycle in sdio.c
>> - Fall back to 3.3 V if the switch repeatedly fails
>> - Add an extra argument to the card_busy host_ops function,
>> which can be used to signal polling use of the function
>>
>> Johan Rudholm (5):
>> mmc: sd: Simplify by using mmc_host_uhs
>> mmc: core: Add mmc_power_cycle
>> mmc: core: Add card_busy to host_ops
>> mmc: core: Break out start_signal_voltage_switch
>> mmc: core: Fixup signal voltage switch
>>
>> drivers/mmc/core/core.c | 114 +++++++++++++++++++++++++++++++++++++++-------
>> drivers/mmc/core/core.h | 5 +-
>> drivers/mmc/core/mmc.c | 8 ++--
>> drivers/mmc/core/sd.c | 27 +++++++----
>> drivers/mmc/core/sdio.c | 23 ++++++++--
>> include/linux/mmc/host.h | 3 ++
>> 6 files changed, 145 insertions(+), 35 deletions(-)
>>
>>
>
> Tested-by: Kevin Liu <kliu5@marvell.com>
>
> Tested with both high speed and UHS sd cards.
> Tested with emmc chip.
> Tested with sdio card (non UHS).
>
> Tested all the patchset together with below patch (update sdhci.c
> accordingly) on sdhci-pxav3 platforms.
>
> From fc6069b79203f64e7efa8dd0bb295bebcd22f710 Mon Sep 17 00:00:00 2001
> From: Kevin Liu <kliu5@marvell.com>
> Date: Fri, 14 Dec 2012 16:44:10 +0800
> Subject: [PATCH v3 3/3] mmc: sdhci: update signal voltage switch code
>
> The protocal related code is moved to core stack. So update the host
> driver accordingly.
I think one patch in this set have not got my ack yet, so to be clear,
for the hole series:
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Chris, unless you see some issues with this patch set, could this be
merged for 3.9? I have some mmci patches that I would like to upstream
that relies on these fixes, and since those goes though Russell's tree
I will always one kernel version behind.
Kind regards
Ulf Hansson
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode
2013-01-28 14:08 [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Johan Rudholm
` (4 preceding siblings ...)
2013-01-28 14:08 ` [PATCH v6 5/5] mmc: core: Fixup signal voltage switch Johan Rudholm
@ 2013-02-11 16:21 ` Chris Ball
2013-02-11 19:09 ` Johan Rudholm
5 siblings, 1 reply; 11+ messages in thread
From: Chris Ball @ 2013-02-11 16:21 UTC (permalink / raw)
To: Johan Rudholm
Cc: linux-mmc, Per Forlin, Ulf Hansson, Fredrik Soderstedt, Kevin Liu,
Philip Rakity, Daniel Drake, Aaron, Subhash Jadavani,
Sujit Reddy Thumma, Wei WANG
Hi Johan,
On Mon, Jan 28 2013, Johan Rudholm wrote:
> This patch series attempts to make the 1.8V signal voltage switch
> required for UHS mode work according to the SD specification.
Thanks, pushed to mmc-next for 3.9.
- Chris.
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode
2013-02-11 16:21 ` [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Chris Ball
@ 2013-02-11 19:09 ` Johan Rudholm
2013-02-11 19:18 ` Chris Ball
0 siblings, 1 reply; 11+ messages in thread
From: Johan Rudholm @ 2013-02-11 19:09 UTC (permalink / raw)
To: Chris Ball
Cc: Johan Rudholm, linux-mmc, Per Forlin, Ulf Hansson,
Fredrik Soderstedt, Kevin Liu, Philip Rakity, Daniel Drake, Aaron,
Subhash Jadavani, Sujit Reddy Thumma, Wei WANG
Hi Chris,
2013/2/11 Chris Ball <cjb@laptop.org>:
> Hi Johan,
>
> On Mon, Jan 28 2013, Johan Rudholm wrote:
>> This patch series attempts to make the 1.8V signal voltage switch
>> required for UHS mode work according to the SD specification.
>
> Thanks, pushed to mmc-next for 3.9.
Cool! Just so we won't forget and break something, have you considered
taking in the following patch too?
>From fc6069b79203f64e7efa8dd0bb295bebcd22f710 Mon Sep 17 00:00:00 2001
From: Kevin Liu <kliu5@marvell.com>
Date: Fri, 14 Dec 2012 16:44:10 +0800
Subject: [PATCH v3 3/3] mmc: sdhci: update signal voltage switch code
otherwise I think that SDHCI may break. Kevin, please correct me if I'm wrong?
Kind regards, Johan
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode
2013-02-11 19:09 ` Johan Rudholm
@ 2013-02-11 19:18 ` Chris Ball
0 siblings, 0 replies; 11+ messages in thread
From: Chris Ball @ 2013-02-11 19:18 UTC (permalink / raw)
To: Johan Rudholm
Cc: Johan Rudholm, linux-mmc, Per Forlin, Ulf Hansson,
Fredrik Soderstedt, Kevin Liu, Philip Rakity, Daniel Drake, Aaron,
Subhash Jadavani, Sujit Reddy Thumma, Wei WANG
Hi,
On Mon, Feb 11 2013, Johan Rudholm wrote:
>> Thanks, pushed to mmc-next for 3.9.
>
> Cool! Just so we won't forget and break something, have you considered
> taking in the following patch too?
>
> From fc6069b79203f64e7efa8dd0bb295bebcd22f710 Mon Sep 17 00:00:00 2001
> From: Kevin Liu <kliu5@marvell.com>
> Date: Fri, 14 Dec 2012 16:44:10 +0800
> Subject: [PATCH v3 3/3] mmc: sdhci: update signal voltage switch code
Ah, thanks for the heads-up. I've pushed this one now too, and will test.
- Chris.
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2013-02-11 19:18 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-28 14:08 [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 1/5] mmc: sd: Simplify by using mmc_host_uhs Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 2/5] mmc: core: Add mmc_power_cycle Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 3/5] mmc: core: Add card_busy to host_ops Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 4/5] mmc: core: Break out start_signal_voltage_switch Johan Rudholm
2013-01-28 14:08 ` [PATCH v6 5/5] mmc: core: Fixup signal voltage switch Johan Rudholm
2013-02-11 16:21 ` [PATCH v6 0/5] mmc: core: Signal voltage switch procedure for UHS mode Chris Ball
2013-02-11 19:09 ` Johan Rudholm
2013-02-11 19:18 ` Chris Ball
[not found] <25B60CDC2F704E4E9D88FFD52780CB4C08B059D33F@SC-VEXCH1.marvell.com>
2013-01-29 4:32 ` Kevin Liu
2013-02-08 8:58 ` Ulf Hansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox