Skip to contentSkip to conversation

ARM: OMAP4: fix MMC failure due to regulator enable/disable ops

PATCH New Balaji T K 2 participants 4 messages Jun 1, 2011

Subsystems (5)
lore
Share & tools
lore

Balaji T K

author
#0 lore raw

v2 cover ARM: OMAP4: fix MMC failure due to regulator enable/disable ops

Balaji T K (2):
ARM: OMAP4: MMC: increase delay for pbias
ARM: OMAP4: MMC: no regulator off during probe for eMMC

 arch/arm/mach-omap2/board-4430sdp.c   |    1 +
 arch/arm/mach-omap2/hsmmc.c           |   16 +++++++++++++---
 arch/arm/mach-omap2/hsmmc.h           |    1 +
 arch/arm/plat-omap/include/plat/mmc.h |    3 +++
 drivers/mmc/host/omap_hsmmc.c         |    3 +++
 5 files changed, 21 insertions(+), 3 deletions(-)
author
#1 lore raw

PATCH v2 1/2 ARM: OMAP4: MMC: increase delay for pbias

4 micro seconds is not enough for PBIAS if MMC regulator is enabled from MMC regulator OFF.
Increase the delay for PBIAS to stabilize.
Wait for PBIAS and timeout if not.

Resolves MMC/SD failure on OMAP4
"Pbias Voltage is not same as LDO"

---
v2:
replace usleep by usleep_range

 arch/arm/mach-omap2/hsmmc.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)
arch/arm/mach-omap2/hsmmc.c +10 -3
index b2f30be..24f25c7 100644
@@ -145,6 +145,7 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
 				 int power_on, int vdd)
 {
 	u32 reg;
+	unsigned long timeout;
 
 	if (power_on) {
 		reg = omap4_ctrl_pad_readl(control_pbias_offset);
@@ -157,9 +158,15 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
 			OMAP4_MMC1_PWRDNZ_MASK |
 			OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
 		omap4_ctrl_pad_writel(reg, control_pbias_offset);
-		/* 4 microsec delay for comparator to generate an error*/
-		udelay(4);
-		reg = omap4_ctrl_pad_readl(control_pbias_offset);
+
+		timeout = jiffies + msecs_to_jiffies(5);
+		do {
+			reg = omap4_ctrl_pad_readl(control_pbias_offset);
+			if (!(reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK))
+				break;
+			usleep_range(100, 200);
+		} while (!time_after(jiffies, timeout));
+
 		if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK) {
 			pr_err("Pbias Voltage is not same as LDO\n");
 			/* Caution : On VMODE_ERROR Power Down MMC IO */
Signature · 1 line
1.7.0.4
maintainer
#2 lore raw

PATCH v2 1/2 ARM: OMAP4: MMC: increase delay for pbias

Quoted 7 lines · Balaji T K

4 micro seconds is not enough for PBIAS if MMC regulator is enabled from MMC regulator OFF.
Increase the delay for PBIAS to stabilize.
Wait for PBIAS and timeout if not.

Resolves MMC/SD failure on OMAP4
"Pbias Voltage is not same as LDO"

Thanks for updating this, applying to devel-fixes.

Tony

author
#3 lore raw

PATCH v2 2/2 ARM: OMAP4: MMC: no regulator off during probe for eMMC

In reply to Balaji T K

eMMC does not handle power off when not in sleep state, Skip regulator disable during probe when eMMC is not in known state - state left by bootloader.

Resolves eMMC failure on OMAP4
mmc0: error -110 whilst initialising MMC card

---
 arch/arm/mach-omap2/board-4430sdp.c   |    1 +
 arch/arm/mach-omap2/hsmmc.c           |    3 +++
 arch/arm/mach-omap2/hsmmc.h           |    1 +
 arch/arm/plat-omap/include/plat/mmc.h |    3 +++
 drivers/mmc/host/omap_hsmmc.c         |    3 +++
 5 files changed, 11 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/board-4430sdp.c +1 -0
index 73fa90b..b324605 100644
@@ -322,6 +322,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.nonremovable   = true,
 		.ocr_mask	= MMC_VDD_29_30,
+		.no_off_init	= true,
 	},
 	{
 		.mmc		= 1,
arch/arm/mach-omap2/hsmmc.c +3 -0
index 24f25c7..66868c5 100644
@@ -338,6 +338,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 	if (c->no_off)
 		mmc->slots[0].no_off = 1;
 
+	if (c->no_off_init)
+		mmc->slots[0].no_regulator_off_init = c->no_off_init;
+
 	if (c->vcc_aux_disable_is_sleep)
 		mmc->slots[0].vcc_aux_disable_is_sleep = 1;
 
arch/arm/mach-omap2/hsmmc.h +1 -0
index f119348..f757e78 100644
@@ -18,6 +18,7 @@ struct omap2_hsmmc_info {
 	bool	nonremovable;	/* Nonremovable e.g. eMMC */
 	bool	power_saving;	/* Try to sleep or power off when possible */
 	bool	no_off;		/* power_saving and power is not to go off */
+	bool	no_off_init;	/* no power off when not in MMC sleep state */
 	bool	vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
 	int	gpio_cd;	/* or -EINVAL */
 	int	gpio_wp;	/* or -EINVAL */
arch/arm/plat-omap/include/plat/mmc.h +3 -0
index f38fef9..c7b8741 100644
@@ -101,6 +101,9 @@ struct omap_mmc_platform_data {
 		/* If using power_saving and the MMC power is not to go off */
 		unsigned no_off:1;
 
+		/* eMMC does not handle power off when not in sleep state */
+		unsigned no_regulator_off_init:1;
+
 		/* Regulator off remapped to sleep */
 		unsigned vcc_aux_disable_is_sleep:1;
 
drivers/mmc/host/omap_hsmmc.c +3 -0
index 259ece0..5b2e215 100644
@@ -435,6 +435,9 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 		reg = regulator_get(host->dev, "vmmc_aux");
 		host->vcc_aux = IS_ERR(reg) ? NULL : reg;
 
+		/* For eMMC do not power off when not in sleep state */
+		if (mmc_slot(host).no_regulator_off_init)
+			return 0;
 		/*
 		* UGLY HACK:  workaround regulator framework bugs.
 		* When the bootloader leaves a supply active, it's
Signature · 1 line
1.7.0.4