linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] omap_hsmmc: voltage switching and tuning
@ 2015-07-30  7:46 Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 01/11] mmc: host: omap_hsmmc: Support vmmc_aux to switch to 1.8v Kishon Vijay Abraham I
                   ` (11 more replies)
  0 siblings, 12 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

Patch series implements voltage switching and tuning for omap_hsmmc
driver.

Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.

Balaji T K (2):
  mmc: host: omap_hsmmc: add voltage switch support for UHS SD card
  mmc: host: omap_hsmmc: add tuning support

Kishon Vijay Abraham I (8):
  mmc: host: omap_hsmmc: Support pbias and vmmc_aux to switch to 1.8v
  mmc: host: omap_hsmmc: separate setting voltage capabilities from bus
    power
  mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by
    mmc core
  mmc: host: omap_hsmmc: set clk rate to the max frequency
  mmc: host: omap_hsmmc: set timing in the UHSMS field
  mmc: host: omap_hsmmc: Workaround for errata id i802
  mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd
  mmc: host: omap_hsmmc: remove incorrect voltage switch sequence

Mugunthan V N (1):
  mmc: host: omap_hsmmc: add software timer when timeout greater than
    hardware capablility

 drivers/mmc/host/omap_hsmmc.c |  670 +++++++++++++++++++++++++++++++++--------
 1 file changed, 547 insertions(+), 123 deletions(-)

-- 
1.7.9.5

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

* [PATCH 01/11] mmc: host: omap_hsmmc: Support vmmc_aux to switch to 1.8v
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 02/11] mmc: host: omap_hsmmc: separate setting voltage capabilities from bus power Kishon Vijay Abraham I
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for vmmc_aux to switch to 1.8v. Also use "iov" instead of
"vdd" to indicate io voltage. This is in preparation for adding support
for io signal voltage switch.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |   47 +++++++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 6d52873..09e949f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -243,10 +243,11 @@ static int omap_hsmmc_get_cover_state(struct device *dev)
 	return mmc_gpio_get_cd(host->mmc);
 }
 
-static int omap_hsmmc_enable_supply(struct mmc_host *mmc)
+static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int iov)
 {
 	int ret;
 	struct mmc_ios *ios = &mmc->ios;
+	int uvoltage;
 
 	if (mmc->supply.vmmc) {
 		ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
@@ -255,7 +256,24 @@ static int omap_hsmmc_enable_supply(struct mmc_host *mmc)
 	}
 
 	/* Enable interface voltage rail, if needed */
-	if (mmc->supply.vqmmc && !regulator_is_enabled(mmc->supply.vqmmc)) {
+	if (mmc->supply.vqmmc) {
+		if (regulator_is_enabled(mmc->supply.vqmmc)) {
+			ret = regulator_disable(mmc->supply.vqmmc);
+			if (ret) {
+				dev_err(mmc_dev(mmc),
+					"vmmc_aux reg disable failed\n");
+				goto err_vqmmc;
+			}
+		}
+
+		uvoltage = (iov == VDD_165_195) ? VDD_1V8 : VDD_3V0;
+		ret = regulator_set_voltage(mmc->supply.vqmmc, uvoltage,
+					    uvoltage);
+		if (ret) {
+			dev_err(mmc_dev(mmc), "vmmc_aux set voltage failed\n");
+			goto err_vqmmc;
+		}
+
 		ret = regulator_enable(mmc->supply.vqmmc);
 		if (ret) {
 			dev_err(mmc_dev(mmc), "vmmc_aux reg enable failed\n");
@@ -304,22 +322,19 @@ err_set_ocr:
 }
 
 static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on,
-				int vdd)
+				int iov)
 {
 	int ret;
+	int uvoltage;
 
 	if (!host->pbias)
 		return 0;
 
 	if (power_on) {
-		if (vdd <= VDD_165_195)
-			ret = regulator_set_voltage(host->pbias, VDD_1V8,
-						    VDD_1V8);
-		else
-			ret = regulator_set_voltage(host->pbias, VDD_3V0,
-						    VDD_3V0);
-		if (ret < 0) {
-			dev_err(host->dev, "pbias set voltage fail\n");
+		uvoltage = (iov <= VDD_165_195) ? VDD_1V8 : VDD_3V0;
+		ret = regulator_set_voltage(host->pbias, uvoltage, uvoltage);
+		if (ret) {
+			dev_err(host->dev, "pbias set voltage failed\n");
 			return ret;
 		}
 
@@ -343,7 +358,7 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on,
 	return 0;
 }
 
-static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
+static int omap_hsmmc_set_power(struct device *dev, int power_on, int iov)
 {
 	struct omap_hsmmc_host *host =
 		platform_get_drvdata(to_platform_device(dev));
@@ -358,7 +373,7 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
 		return 0;
 
 	if (mmc_pdata(host)->before_set_reg)
-		mmc_pdata(host)->before_set_reg(dev, power_on, vdd);
+		mmc_pdata(host)->before_set_reg(dev, power_on, iov);
 
 	ret = omap_hsmmc_set_pbias(host, false, 0);
 	if (ret)
@@ -378,11 +393,11 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
 	 * chips/cards need an interface voltage rail too.
 	 */
 	if (power_on) {
-		ret = omap_hsmmc_enable_supply(mmc);
+		ret = omap_hsmmc_enable_supply(mmc, iov);
 		if (ret)
 			return ret;
 
-		ret = omap_hsmmc_set_pbias(host, true, vdd);
+		ret = omap_hsmmc_set_pbias(host, true, iov);
 		if (ret)
 			goto err_set_voltage;
 	} else {
@@ -392,7 +407,7 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
 	}
 
 	if (mmc_pdata(host)->after_set_reg)
-		mmc_pdata(host)->after_set_reg(dev, power_on, vdd);
+		mmc_pdata(host)->after_set_reg(dev, power_on, iov);
 
 	return 0;
 
-- 
1.7.9.5

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

* [PATCH 02/11] mmc: host: omap_hsmmc: separate setting voltage capabilities from bus power
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 01/11] mmc: host: omap_hsmmc: Support vmmc_aux to switch to 1.8v Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 03/11] mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by mmc core Kishon Vijay Abraham I
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

Added a separate function to set the voltage capabilities of the host
controller. Voltage capabilities should be set only once during
controller initialization but bus power can be changed every time there
is a voltage switch and whenever a different card is inserted.
This allows omap_hsmmc_conf_bus_power to be invoked every time there
is a voltage switch.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |   28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 09e949f..2dfef11 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1812,25 +1812,34 @@ err:
 	return ret;
 }
 
+static void omap_hsmmc_set_capabilities(struct omap_hsmmc_host *host)
+{
+	u32 val;
+
+	val = OMAP_HSMMC_READ(host->base, CAPA);
+
+	/* Only MMC1 supports 3.0V */
+	if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT)
+		val |= (VS30 | VS18);
+	else
+		val |= VS18;
+
+	OMAP_HSMMC_WRITE(host->base, CAPA, val);
+}
+
 static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
 {
-	u32 hctl, capa, value;
+	u32 hctl, value;
 
 	/* Only MMC1 supports 3.0V */
-	if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
+	if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT)
 		hctl = SDVS30;
-		capa = VS30 | VS18;
-	} else {
+	else
 		hctl = SDVS18;
-		capa = VS18;
-	}
 
 	value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
 	OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
 
-	value = OMAP_HSMMC_READ(host->base, CAPA);
-	OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
-
 	/* Set SD bus power bit */
 	set_sd_bus_power(host);
 }
@@ -2133,6 +2142,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 	mmc->pm_caps |= mmc_pdata(host)->pm_caps;
 
+	omap_hsmmc_set_capabilities(host);
 	omap_hsmmc_conf_bus_power(host);
 
 	if (!pdev->dev.of_node) {
-- 
1.7.9.5

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

* [PATCH 03/11] mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by mmc core
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 01/11] mmc: host: omap_hsmmc: Support vmmc_aux to switch to 1.8v Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 02/11] mmc: host: omap_hsmmc: separate setting voltage capabilities from bus power Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 04/11] mmc: host: omap_hsmmc: add voltage switch support for UHS SD card Kishon Vijay Abraham I
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

HCTL is now set based on ios.signal_voltage set by mmc core and not
hardcoded to 3V0 if OMAP_HSMMC_SUPPORTS_DUAL_VOLT is set. If
OMAP_HSMMC_SUPPORTS_DUAL_VOLT is set, it means HCTL can be set to either
3V0 or 1V8. And it should be set to 3V0 or 1V8 depending on
ios.signal_voltage.
Also it is now set on power mode status being changed to MMC_POWER_ON.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2dfef11..306e5c0 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -228,6 +228,7 @@ struct omap_mmc_of_data {
 };
 
 static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host);
+static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov);
 
 static int omap_hsmmc_card_detect(struct device *dev)
 {
@@ -1665,6 +1666,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			mmc_pdata(host)->set_power(host->dev, 1, ios->vdd);
 			break;
 		case MMC_POWER_ON:
+			omap_hsmmc_conf_bus_power(host, ios->signal_voltage);
 			do_send_init_stream = 1;
 			break;
 		}
@@ -1827,17 +1829,12 @@ static void omap_hsmmc_set_capabilities(struct omap_hsmmc_host *host)
 	OMAP_HSMMC_WRITE(host->base, CAPA, val);
 }
 
-static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
+static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov)
 {
 	u32 hctl, value;
 
-	/* Only MMC1 supports 3.0V */
-	if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT)
-		hctl = SDVS30;
-	else
-		hctl = SDVS18;
-
 	value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
+	hctl = (iov == MMC_SIGNAL_VOLTAGE_180) ? SDVS18 : SDVS30;
 	OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
 
 	/* Set SD bus power bit */
@@ -2143,7 +2140,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 	mmc->pm_caps |= mmc_pdata(host)->pm_caps;
 
 	omap_hsmmc_set_capabilities(host);
-	omap_hsmmc_conf_bus_power(host);
 
 	if (!pdev->dev.of_node) {
 		res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
@@ -2318,6 +2314,7 @@ static int omap_hsmmc_suspend(struct device *dev)
 static int omap_hsmmc_resume(struct device *dev)
 {
 	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct mmc_ios *ios;
 
 	if (!host)
 		return 0;
@@ -2327,8 +2324,9 @@ static int omap_hsmmc_resume(struct device *dev)
 	if (host->dbclk)
 		clk_prepare_enable(host->dbclk);
 
+	ios = &host->mmc->ios;
 	if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
-		omap_hsmmc_conf_bus_power(host);
+		omap_hsmmc_conf_bus_power(host, ios->signal_voltage);
 
 	omap_hsmmc_protect_card(host);
 	pm_runtime_mark_last_busy(host->dev);
-- 
1.7.9.5

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

* [PATCH 04/11] mmc: host: omap_hsmmc: add voltage switch support for UHS SD card
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (2 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 03/11] mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by mmc core Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 05/11] mmc: host: omap_hsmmc: set clk rate to the max frequency Kishon Vijay Abraham I
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Balaji T K <balajitk@ti.com>

UHS sd card i/o data line can operate at 3V and 1.8V on UHS speed
modes. Add support for signal voltage switch and check for card_busy.

Signed-off-by: Balaji T K <balajitk@ti.com>
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
[kishon at ti.com : cleanup the voltage switch sequence]
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |  129 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 129 insertions(+)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 306e5c0..e960b5c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -112,6 +112,9 @@
 /* PSTATE */
 #define DLEV_DAT(x)		(1 << (20 + (x)))
 
+/* AC12 */
+#define AC12_V1V8_SIGEN		(1 << 19)
+
 /* Interrupt masks for IE and ISE register */
 #define CC_EN			(1 << 0)
 #define TC_EN			(1 << 1)
@@ -151,6 +154,12 @@
 #define VDD_1V8			1800000		/* 180000 uV */
 #define VDD_3V0			3000000		/* 300000 uV */
 #define VDD_165_195		(ffs(MMC_VDD_165_195) - 1)
+#define VDD_30_31		(ffs(MMC_VDD_30_31) - 1)
+
+#define CON_CLKEXTFREE		(1 << 16)
+#define CON_PADEN		(1 << 15)
+#define PSTATE_CLEV		(1 << 24)
+#define PSTATE_DLEV		(0xF << 20)
 
 /*
  * One controller can have multiple slots, like on some omap boards using
@@ -1851,6 +1860,124 @@ static int omap_hsmmc_multi_io_quirk(struct mmc_card *card,
 	return blk_size;
 }
 
+static int omap_hsmmc_start_signal_voltage_switch(struct mmc_host *mmc,
+						  struct mmc_ios *ios)
+{
+	struct omap_hsmmc_host *host;
+	u32 val = 0;
+	int ret = 0;
+
+	host  = mmc_priv(mmc);
+
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+		val = OMAP_HSMMC_READ(host->base, CAPA);
+		if (!(val & VS30))
+			return -EOPNOTSUPP;
+
+		omap_hsmmc_conf_bus_power(host, ios->signal_voltage);
+
+		val = OMAP_HSMMC_READ(host->base, AC12);
+		val &= ~AC12_V1V8_SIGEN;
+		OMAP_HSMMC_WRITE(host->base, AC12, val);
+
+		ret = mmc_pdata(host)->set_power(host->dev, 1, VDD_30_31);
+		if (ret) {
+			dev_dbg(mmc_dev(host->mmc), "failed to switch to 3v\n");
+			return ret;
+		}
+
+		dev_dbg(mmc_dev(host->mmc), " i/o voltage switch to 3V\n");
+	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+		val = OMAP_HSMMC_READ(host->base, CAPA);
+		if (!(val & VS18))
+			return -EOPNOTSUPP;
+
+		omap_hsmmc_conf_bus_power(host, ios->signal_voltage);
+
+		val = OMAP_HSMMC_READ(host->base, AC12);
+		val |= AC12_V1V8_SIGEN;
+		OMAP_HSMMC_WRITE(host->base, AC12, val);
+
+		ret = mmc_pdata(host)->set_power(host->dev, 1, VDD_165_195);
+		if (ret < 0) {
+			dev_dbg(mmc_dev(host->mmc), "failed to switch 1.8v\n");
+			return ret;
+		}
+	} else {
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int omap_hsmmc_card_busy_low(struct omap_hsmmc_host *host)
+{
+	u32 val;
+	unsigned long timeout;
+
+	val = OMAP_HSMMC_READ(host->base, CON);
+	val &= ~CON_CLKEXTFREE;
+	val |= CON_PADEN;
+	OMAP_HSMMC_WRITE(host->base, CON, val);
+
+	timeout = jiffies + msecs_to_jiffies(1);
+	do {
+		val = OMAP_HSMMC_READ(host->base, PSTATE);
+		if (!(val & (PSTATE_CLEV | PSTATE_DLEV)))
+			return true;
+
+		usleep_range(100, 200);
+	} while (!time_after(jiffies, timeout));
+
+	dev_err(mmc_dev(host->mmc), "timeout : i/o low 0x%x\n", val);
+
+	return false;
+}
+
+static int omap_hsmmc_card_busy_high(struct omap_hsmmc_host *host)
+{
+	u32 val;
+	unsigned long timeout;
+
+	val = OMAP_HSMMC_READ(host->base, CON);
+	val |= CLKEXTFREE;
+	OMAP_HSMMC_WRITE(host->base, CON, val);
+
+	timeout = jiffies + msecs_to_jiffies(1);
+	do {
+		val = OMAP_HSMMC_READ(host->base, PSTATE);
+		if ((val & PSTATE_CLEV) && (val & PSTATE_DLEV)) {
+			val = OMAP_HSMMC_READ(host->base, CON);
+			val &= ~(CON_CLKEXTFREE | CON_PADEN);
+			OMAP_HSMMC_WRITE(host->base, CON, val);
+			return false;
+		}
+
+		usleep_range(100, 200);
+	} while (!time_after(jiffies, timeout));
+
+	dev_err(mmc_dev(host->mmc), "timeout : i/o high 0x%x\n", val);
+
+	return true;
+}
+
+static int omap_hsmmc_card_busy(struct mmc_host *mmc)
+{
+	struct omap_hsmmc_host *host;
+	u32 val;
+	int ret;
+
+	host  = mmc_priv(mmc);
+
+	val = OMAP_HSMMC_READ(host->base, AC12);
+	if (val & AC12_V1V8_SIGEN)
+		ret = omap_hsmmc_card_busy_high(host);
+	else
+		ret = omap_hsmmc_card_busy_low(host);
+
+	return ret;
+}
+
 static struct mmc_host_ops omap_hsmmc_ops = {
 	.post_req = omap_hsmmc_post_req,
 	.pre_req = omap_hsmmc_pre_req,
@@ -1860,6 +1987,8 @@ static struct mmc_host_ops omap_hsmmc_ops = {
 	.get_ro = mmc_gpio_get_ro,
 	.init_card = omap_hsmmc_init_card,
 	.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
+	.start_signal_voltage_switch = omap_hsmmc_start_signal_voltage_switch,
+	.card_busy = omap_hsmmc_card_busy,
 };
 
 #ifdef CONFIG_DEBUG_FS
-- 
1.7.9.5

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

* [PATCH 05/11] mmc: host: omap_hsmmc: set clk rate to the max frequency
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (3 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 04/11] mmc: host: omap_hsmmc: add voltage switch support for UHS SD card Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 06/11] mmc: host: omap_hsmmc: set timing in the UHSMS field Kishon Vijay Abraham I
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

Set the clock rate of the functional clock to the max frequency
that is passed to the driver either using pdata or dt.

Also remove unnecessary setting of host->fclk to NULL.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index e960b5c..0452a8b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2219,7 +2219,12 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 	host->fclk = devm_clk_get(&pdev->dev, "fck");
 	if (IS_ERR(host->fclk)) {
 		ret = PTR_ERR(host->fclk);
-		host->fclk = NULL;
+		goto err1;
+	}
+
+	ret = clk_set_rate(host->fclk, mmc->f_max);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to set clock to %d\n", mmc->f_max);
 		goto err1;
 	}
 
-- 
1.7.9.5

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

* [PATCH 06/11] mmc: host: omap_hsmmc: set timing in the UHSMS field
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (4 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 05/11] mmc: host: omap_hsmmc: set clk rate to the max frequency Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 07/11] mmc: host: omap_hsmmc: add tuning support Kishon Vijay Abraham I
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add a separate function to set the UHSMS field to one
of SDR104, SDR50, DDR50, SDR25 or SDR12 depending on the
inserted SD card. This is required for
tuning to succeed in the case of SDR104/HS200 or SDR50.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |   49 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 0452a8b..e0bd8df 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -114,6 +114,13 @@
 
 /* AC12 */
 #define AC12_V1V8_SIGEN		(1 << 19)
+#define AC12_UHSMC_MASK		(7 << 16)
+#define AC12_UHSMC_SDR12	(0 << 16)
+#define AC12_UHSMC_SDR25	(1 << 16)
+#define AC12_UHSMC_SDR50	(2 << 16)
+#define AC12_UHSMC_SDR104	(3 << 16)
+#define AC12_UHSMC_DDR50	(4 << 16)
+#define AC12_UHSMC_RES		(0x7 << 16)
 
 /* Interrupt masks for IE and ISE register */
 #define CC_EN			(1 << 0)
@@ -198,6 +205,7 @@ struct omap_hsmmc_host {
 	unsigned int		dma_sg_idx;
 	unsigned char		bus_mode;
 	unsigned char		power_mode;
+	unsigned char		timing;
 	int			suspended;
 	u32			con;
 	u32			hctl;
@@ -1658,6 +1666,41 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req)
 	omap_hsmmc_start_command(host, req->cmd, req->data);
 }
 
+static void omap_hsmmc_set_timing(struct omap_hsmmc_host *host)
+{
+	u32 val;
+	struct mmc_ios *ios = &host->mmc->ios;
+
+	omap_hsmmc_stop_clock(host);
+
+	val = OMAP_HSMMC_READ(host->base, AC12);
+	val &= ~AC12_UHSMC_MASK;
+	switch (ios->timing) {
+	case MMC_TIMING_UHS_SDR104:
+	case MMC_TIMING_MMC_HS200:
+		val |= AC12_UHSMC_SDR104;
+		break;
+	case MMC_TIMING_UHS_DDR50:
+		val |= AC12_UHSMC_DDR50;
+		break;
+	case MMC_TIMING_UHS_SDR50:
+		val |= AC12_UHSMC_SDR50;
+		break;
+	case MMC_TIMING_UHS_SDR25:
+		val |= AC12_UHSMC_SDR25;
+		break;
+	case MMC_TIMING_UHS_SDR12:
+		val |= AC12_UHSMC_SDR12;
+		break;
+	default:
+		val |= AC12_UHSMC_RES;
+		break;
+	}
+	OMAP_HSMMC_WRITE(host->base, AC12, val);
+
+	omap_hsmmc_start_clock(host);
+}
+
 /* Routine to configure clock values. Exposed API to core */
 static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
@@ -1706,6 +1749,11 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
 	omap_hsmmc_set_clock(host);
 
+	if (ios->timing != host->timing) {
+		omap_hsmmc_set_timing(host);
+		host->timing = ios->timing;
+	}
+
 	if (do_send_init_stream)
 		send_init_stream(host);
 
@@ -2194,6 +2242,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 	host->mapbase	= res->start + pdata->reg_offset;
 	host->base	= base + pdata->reg_offset;
 	host->power_mode = MMC_POWER_OFF;
+	host->timing	= 0;
 	host->next_data.cookie = 1;
 
 	ret = omap_hsmmc_gpio_init(mmc, host, pdata);
-- 
1.7.9.5

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

* [PATCH 07/11] mmc: host: omap_hsmmc: add tuning support
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (5 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 06/11] mmc: host: omap_hsmmc: set timing in the UHSMS field Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 08/11] mmc: host: omap_hsmmc: Workaround for errata id i802 Kishon Vijay Abraham I
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Balaji T K <balajitk@ti.com>

MMC tuning procedure is required to support SD card
UHS1-SDR104 mode and EMMC HS200 mode.

The tuning function omap_execute_tuning() will only
be called by the MMC/SD core if the corresponding
speed modes are supported by the OMAP silicon which
is set in the mmc host "caps" field.

Signed-off-by: Balaji T K <balajitk@ti.com>
Signed-off-by: Viswanath Puttagunta <vishp@ti.com>
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
[kishon at ti.com : cleanup the tuning sequence]
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |  234 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 232 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index e0bd8df..dcfa92e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <linux/dmaengine.h>
 #include <linux/seq_file.h>
@@ -49,6 +50,7 @@
 /* OMAP HSMMC Host Controller Registers */
 #define OMAP_HSMMC_SYSSTATUS	0x0014
 #define OMAP_HSMMC_CON		0x002C
+#define OMAP_HSMMC_DLL		0x0034
 #define OMAP_HSMMC_SDMASA	0x0100
 #define OMAP_HSMMC_BLK		0x0104
 #define OMAP_HSMMC_ARG		0x0108
@@ -66,6 +68,7 @@
 #define OMAP_HSMMC_ISE		0x0138
 #define OMAP_HSMMC_AC12		0x013C
 #define OMAP_HSMMC_CAPA		0x0140
+#define OMAP_HSMMC_CAPA2	0x0144
 
 #define VS18			(1 << 26)
 #define VS30			(1 << 25)
@@ -114,6 +117,7 @@
 
 /* AC12 */
 #define AC12_V1V8_SIGEN		(1 << 19)
+#define AC12_SCLK_SEL		(1 << 23)
 #define AC12_UHSMC_MASK		(7 << 16)
 #define AC12_UHSMC_SDR12	(0 << 16)
 #define AC12_UHSMC_SDR25	(1 << 16)
@@ -122,6 +126,18 @@
 #define AC12_UHSMC_DDR50	(4 << 16)
 #define AC12_UHSMC_RES		(0x7 << 16)
 
+/* DLL */
+#define DLL_SWT			(1 << 20)
+#define DLL_FORCE_SR_C_SHIFT	13
+#define DLL_FORCE_SR_C_MASK	0x7f
+#define DLL_FORCE_VALUE		(1 << 12)
+#define DLL_CALIB		(1 << 1)
+
+#define MAX_PHASE_DELAY		0x7c
+
+/* CAPA2 */
+#define CAPA2_TSDR50		(1 << 13)
+
 /* Interrupt masks for IE and ISE register */
 #define CC_EN			(1 << 0)
 #define TC_EN			(1 << 1)
@@ -201,6 +217,7 @@ struct omap_hsmmc_host {
 	void	__iomem		*base;
 	resource_size_t		mapbase;
 	spinlock_t		irq_lock; /* Prevent races with irq handler */
+	struct completion	buf_ready;
 	unsigned int		dma_len;
 	unsigned int		dma_sg_idx;
 	unsigned char		bus_mode;
@@ -228,6 +245,9 @@ struct omap_hsmmc_host {
 	struct omap_hsmmc_next	next_data;
 	struct	omap_hsmmc_platform_data	*pdata;
 
+	u32			*tuning_data;
+	int			tuning_size;
+
 	/* return MMC cover switch state, can be NULL if not supported.
 	 *
 	 * possible return values:
@@ -244,8 +264,39 @@ struct omap_mmc_of_data {
 	u8 controller_flags;
 };
 
+static const u8 ref_tuning_4bits[] = {
+	0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
+	0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
+	0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
+	0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
+	0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
+	0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
+	0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
+	0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
+};
+
+static const u8 ref_tuning_8bits[] = {
+	0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+	0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
+	0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
+	0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
+	0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
+	0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
+	0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
+	0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
+	0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
+	0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
+	0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
+	0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
+	0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
+	0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
+	0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
+	0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
+};
+
 static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host);
 static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov);
+static void omap_hsmmc_disable_tuning(struct omap_hsmmc_host *host);
 
 static int omap_hsmmc_card_detect(struct device *dev)
 {
@@ -600,8 +651,12 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
 {
 	u32 irq_mask = INT_EN_MASK;
 	unsigned long flags;
+	bool is_tuning;
 
-	if (host->use_dma)
+	is_tuning = (cmd->opcode == MMC_SEND_TUNING_BLOCK) ||
+		    (cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200);
+
+	if (!is_tuning && host->use_dma)
 		irq_mask &= ~(BRR_EN | BWR_EN);
 
 	/* Disable timeout for erases */
@@ -947,7 +1002,11 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
 			cmdreg &= ~(DDIR);
 	}
 
-	if (host->use_dma)
+	/* Tuning command is special. Data Present Select should be set */
+	if ((cmd->opcode == MMC_SEND_TUNING_BLOCK) ||
+	    (cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200))
+		cmdreg |= DP_SELECT | DDIR;
+	else if (host->use_dma)
 		cmdreg |= DMAE;
 
 	host->req_in_progress = 1;
@@ -1178,6 +1237,7 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
 	struct mmc_data *data;
 	int end_cmd = 0, end_trans = 0;
 	int error = 0;
+	int i;
 
 	data = host->data;
 	dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
@@ -1213,6 +1273,13 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
 		}
 	}
 
+	if (status & BRR_EN) {
+		for (i = 0; i < host->tuning_size / 4; i++)
+			host->tuning_data[i] =
+				OMAP_HSMMC_READ(host->base, DATA);
+		complete(&host->buf_ready);
+	}
+
 	OMAP_HSMMC_WRITE(host->base, STAT, status);
 	if (end_cmd || ((status & CC_EN) && host->cmd))
 		omap_hsmmc_cmd_done(host, host->cmd);
@@ -1712,6 +1779,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	if (ios->power_mode != host->power_mode) {
 		switch (ios->power_mode) {
 		case MMC_POWER_OFF:
+			omap_hsmmc_disable_tuning(host);
 			mmc_pdata(host)->set_power(host->dev, 0, 0);
 			break;
 		case MMC_POWER_UP:
@@ -2026,6 +2094,166 @@ static int omap_hsmmc_card_busy(struct mmc_host *mmc)
 	return ret;
 }
 
+static inline void omap_hsmmc_set_dll(struct omap_hsmmc_host *host, int count)
+{
+	int i;
+	u32 dll;
+
+	dll = OMAP_HSMMC_READ(host->base, DLL);
+	dll |= DLL_FORCE_VALUE;
+	dll &= ~(DLL_FORCE_SR_C_MASK << DLL_FORCE_SR_C_SHIFT);
+	dll |= (count << DLL_FORCE_SR_C_SHIFT);
+	OMAP_HSMMC_WRITE(host->base, DLL, dll);
+
+	dll |= DLL_CALIB;
+	OMAP_HSMMC_WRITE(host->base, DLL, dll);
+	for (i = 0; i < 1000; i++) {
+		if (OMAP_HSMMC_READ(host->base, DLL) & DLL_CALIB)
+			break;
+	}
+	dll &= ~DLL_CALIB;
+	OMAP_HSMMC_WRITE(host->base, DLL, dll);
+}
+
+static void omap_hsmmc_disable_tuning(struct omap_hsmmc_host *host)
+{
+	int val;
+
+	val = OMAP_HSMMC_READ(host->base, AC12);
+	val &= ~(AC12_SCLK_SEL);
+	OMAP_HSMMC_WRITE(host->base, AC12, val);
+
+	val = OMAP_HSMMC_READ(host->base, DLL);
+	val &= ~(DLL_FORCE_VALUE | DLL_SWT);
+	OMAP_HSMMC_WRITE(host->base, DLL, val);
+}
+
+static int omap_hsmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+	u32 val;
+	u8 cur_match, prev_match = 0;
+	int ret;
+	u32 phase_delay = 0;
+	u32 start_window = 0, max_window = 0;
+	u32 length = 0, max_len = 0;
+	const u8 *tuning_ref;
+	struct mmc_ios *ios = &mmc->ios;
+	struct omap_hsmmc_host *host;
+	struct mmc_command cmd = {0};
+	struct mmc_request mrq = {NULL};
+
+	/* clock tuning is not needed for upto 52MHz */
+	if (ios->clock <= OMAP_MMC_MAX_CLOCK)
+		return 0;
+
+	host = mmc_priv(mmc);
+
+	val = OMAP_HSMMC_READ(host->base, CAPA2);
+	if (ios->timing == MMC_TIMING_UHS_SDR50 && !(val & CAPA2_TSDR50))
+		return 0;
+
+	switch (ios->bus_width) {
+	case MMC_BUS_WIDTH_8:
+		tuning_ref = ref_tuning_8bits;
+		host->tuning_size = sizeof(ref_tuning_8bits);
+		break;
+	case MMC_BUS_WIDTH_4:
+		tuning_ref = ref_tuning_4bits;
+		host->tuning_size = sizeof(ref_tuning_4bits);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	host->tuning_data = kzalloc(host->tuning_size, GFP_KERNEL);
+	if (!host->tuning_data)
+		return -ENOMEM;
+
+	val = OMAP_HSMMC_READ(host->base, DLL);
+	val |= DLL_SWT;
+	OMAP_HSMMC_WRITE(host->base, DLL, val);
+
+	while (phase_delay <= MAX_PHASE_DELAY) {
+		omap_hsmmc_set_dll(host, phase_delay);
+
+		cmd.opcode = opcode;
+		cmd.arg = 0;
+		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+		cmd.retries = 0;
+		cmd.data = NULL;
+		cmd.error = 0;
+
+		mrq.cmd = &cmd;
+		host->mrq = &mrq;
+		OMAP_HSMMC_WRITE(host->base, BLK, host->tuning_size);
+		set_data_timeout(host, 150000000, 0);
+		omap_hsmmc_start_command(host, &cmd, NULL);
+		host->cmd = NULL;
+		host->mrq = NULL;
+
+		ret = wait_for_completion_timeout(&host->buf_ready,
+						  msecs_to_jiffies(5000));
+		if (ret == 0) {
+			dev_err(mmc_dev(host->mmc), "Tuning BRR timeout");
+			ret = -ETIMEDOUT;
+			goto tuning_error;
+		}
+
+		host->req_in_progress = false;
+
+		cur_match = !memcmp(host->tuning_data, tuning_ref,
+				    host->tuning_size);
+		if (cur_match) {
+			if (prev_match) {
+				length++;
+			} else {
+				start_window = phase_delay;
+				length = 1;
+			}
+		}
+
+		if (length > max_len) {
+			max_window = start_window;
+			max_len = length;
+		}
+
+		prev_match = cur_match;
+		phase_delay += 4;
+	}
+
+	if (!max_len) {
+		dev_err(mmc_dev(host->mmc), "Unable to find match\n");
+		ret = -EIO;
+		goto tuning_error;
+	}
+
+	val = OMAP_HSMMC_READ(host->base, AC12);
+	if (!(val & AC12_SCLK_SEL)) {
+		ret = -EIO;
+		goto tuning_error;
+	}
+
+	phase_delay = max_window + 4 * (max_len >> 1);
+	omap_hsmmc_set_dll(host, phase_delay);
+
+	omap_hsmmc_reset_controller_fsm(host, SRD);
+	omap_hsmmc_reset_controller_fsm(host, SRC);
+
+	kfree(host->tuning_data);
+	return 0;
+
+tuning_error:
+	dev_err(mmc_dev(host->mmc),
+		"Tuning failed. Using fixed sampling clock\n");
+
+	omap_hsmmc_disable_tuning(host);
+	omap_hsmmc_reset_controller_fsm(host, SRD);
+	omap_hsmmc_reset_controller_fsm(host, SRC);
+
+	kfree(host->tuning_data);
+	return ret;
+}
+
 static struct mmc_host_ops omap_hsmmc_ops = {
 	.post_req = omap_hsmmc_post_req,
 	.pre_req = omap_hsmmc_pre_req,
@@ -2037,6 +2265,7 @@ static struct mmc_host_ops omap_hsmmc_ops = {
 	.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
 	.start_signal_voltage_switch = omap_hsmmc_start_signal_voltage_switch,
 	.card_busy = omap_hsmmc_card_busy,
+	.execute_tuning = omap_hsmmc_execute_tuning,
 };
 
 #ifdef CONFIG_DEBUG_FS
@@ -2264,6 +2493,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 		mmc->f_max = OMAP_MMC_MAX_CLOCK;
 
 	spin_lock_init(&host->irq_lock);
+	init_completion(&host->buf_ready);
 
 	host->fclk = devm_clk_get(&pdev->dev, "fck");
 	if (IS_ERR(host->fclk)) {
-- 
1.7.9.5

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

* [PATCH 08/11] mmc: host: omap_hsmmc: Workaround for errata id i802
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (6 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 07/11] mmc: host: omap_hsmmc: add tuning support Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 09/11] mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd Kishon Vijay Abraham I
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

According to errata i802, DCRC error interrupts
(MMCHS_STAT[21] DCRC=0x1) can occur during the tuning procedure.

The DCRC interrupt, occurs when the last tuning block fails
(the last ratio tested). The delay from CRC check until the
interrupt is asserted is bigger than the delay until assertion
of the tuning end flag. Assertion of tuning end flag is what
masks the interrupts. Because of this race, an erroneous DCRC
interrupt occurs.

The suggested  workaround is to disable DCRC interrupts during
the tuning procedure which is implemented here.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index dcfa92e..96dd406 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -656,8 +656,17 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
 	is_tuning = (cmd->opcode == MMC_SEND_TUNING_BLOCK) ||
 		    (cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200);
 
-	if (!is_tuning && host->use_dma)
+	if (is_tuning) {
+		/*
+		 * OMAP5/DRA74X/DRA72x Errata i802:
+		 * DCRC error interrupts (MMCHS_STAT[21] DCRC=0x1) can occur
+		 * during the tuning procedure. So disable it during the
+		 * tuning procedure.
+		 */
+		irq_mask &= ~DCRC_EN;
+	} else if (host->use_dma) {
 		irq_mask &= ~(BRR_EN | BWR_EN);
+	}
 
 	/* Disable timeout for erases */
 	if (cmd->opcode == MMC_ERASE)
-- 
1.7.9.5

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

* [PATCH 09/11] mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (7 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 08/11] mmc: host: omap_hsmmc: Workaround for errata id i802 Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 10/11] mmc: host: omap_hsmmc: remove incorrect voltage switch sequence Kishon Vijay Abraham I
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

Now that vmmc regulator is made optional, do not bail out if vmmc
regulator is not found.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |    7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 96dd406..26010a3 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -434,13 +434,6 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int iov)
 	struct mmc_host *mmc = host->mmc;
 	int ret = 0;
 
-	/*
-	 * If we don't see a Vcc regulator, assume it's a fixed
-	 * voltage always-on regulator.
-	 */
-	if (!mmc->supply.vmmc)
-		return 0;
-
 	if (mmc_pdata(host)->before_set_reg)
 		mmc_pdata(host)->before_set_reg(dev, power_on, iov);
 
-- 
1.7.9.5

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

* [PATCH 10/11] mmc: host: omap_hsmmc: remove incorrect voltage switch sequence
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (8 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 09/11] mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-07-30  7:46 ` [PATCH 11/11] mmc: host: omap_hsmmc: add software timer when timeout greater than hardware capablility Kishon Vijay Abraham I
  2015-08-05 10:43 ` [PATCH 00/11] omap_hsmmc: voltage switching and tuning Tony Lindgren
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

ios->vdd is set only in mmc_power_up and mmc_power_off and not in
mmc_select_voltage as mentioned in the code comment. This seems to be
legacy code that has been carried for a long time without being
tested.
This will be replaced with a proper voltage switch sequence and
populated in start_signal_voltage_switch ops to be used by
mmc core for switching voltages.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |   81 -----------------------------------------
 1 file changed, 81 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 26010a3..6b02c7c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1325,69 +1325,6 @@ static void set_sd_bus_power(struct omap_hsmmc_host *host)
 	}
 }
 
-/*
- * Switch MMC interface voltage ... only relevant for MMC1.
- *
- * MMC2 and MMC3 use fixed 1.8V levels, and maybe a transceiver.
- * The MMC2 transceiver controls are used instead of DAT4..DAT7.
- * Some chips, like eMMC ones, use internal transceivers.
- */
-static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd)
-{
-	u32 reg_val = 0;
-	int ret;
-
-	/* Disable the clocks */
-	pm_runtime_put_sync(host->dev);
-	if (host->dbclk)
-		clk_disable_unprepare(host->dbclk);
-
-	/* Turn the power off */
-	ret = mmc_pdata(host)->set_power(host->dev, 0, 0);
-
-	/* Turn the power ON with given VDD 1.8 or 3.0v */
-	if (!ret)
-		ret = mmc_pdata(host)->set_power(host->dev, 1, vdd);
-	pm_runtime_get_sync(host->dev);
-	if (host->dbclk)
-		clk_prepare_enable(host->dbclk);
-
-	if (ret != 0)
-		goto err;
-
-	OMAP_HSMMC_WRITE(host->base, HCTL,
-		OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR);
-	reg_val = OMAP_HSMMC_READ(host->base, HCTL);
-
-	/*
-	 * If a MMC dual voltage card is detected, the set_ios fn calls
-	 * this fn with VDD bit set for 1.8V. Upon card removal from the
-	 * slot, omap_hsmmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF.
-	 *
-	 * Cope with a bit of slop in the range ... per data sheets:
-	 *  - "1.8V" for vdds_mmc1/vdds_mmc1a can be up to 2.45V max,
-	 *    but recommended values are 1.71V to 1.89V
-	 *  - "3.0V" for vdds_mmc1/vdds_mmc1a can be up to 3.5V max,
-	 *    but recommended values are 2.7V to 3.3V
-	 *
-	 * Board setup code shouldn't permit anything very out-of-range.
-	 * TWL4030-family VMMC1 and VSIM regulators are fine (avoiding the
-	 * middle range) but VSIM can't power DAT4..DAT7 at more than 3V.
-	 */
-	if ((1 << vdd) <= MMC_VDD_23_24)
-		reg_val |= SDVS18;
-	else
-		reg_val |= SDVS30;
-
-	OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
-	set_sd_bus_power(host);
-
-	return 0;
-err:
-	dev_err(mmc_dev(host->mmc), "Unable to switch operating voltage\n");
-	return ret;
-}
-
 /* Protect the card while the cover is open */
 static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
 {
@@ -1799,24 +1736,6 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
 	omap_hsmmc_set_bus_width(host);
 
-	if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
-		/* Only MMC1 can interface at 3V without some flavor
-		 * of external transceiver; but they all handle 1.8V.
-		 */
-		if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) &&
-			(ios->vdd == DUAL_VOLT_OCR_BIT)) {
-				/*
-				 * The mmc_select_voltage fn of the core does
-				 * not seem to set the power_mode to
-				 * MMC_POWER_UP upon recalculating the voltage.
-				 * vdd 1.8v.
-				 */
-			if (omap_hsmmc_switch_opcond(host, ios->vdd) != 0)
-				dev_dbg(mmc_dev(host->mmc),
-						"Switch operation failed\n");
-		}
-	}
-
 	omap_hsmmc_set_clock(host);
 
 	if (ios->timing != host->timing) {
-- 
1.7.9.5

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

* [PATCH 11/11] mmc: host: omap_hsmmc: add software timer when timeout greater than hardware capablility
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (9 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 10/11] mmc: host: omap_hsmmc: remove incorrect voltage switch sequence Kishon Vijay Abraham I
@ 2015-07-30  7:46 ` Kishon Vijay Abraham I
  2015-08-05 10:43 ` [PATCH 00/11] omap_hsmmc: voltage switching and tuning Tony Lindgren
  11 siblings, 0 replies; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-07-30  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mugunthan V N <mugunthanvnm@ti.com>

DRA7 Errata No i834: When using high speed HS200 and SDR104
cards, the functional clock for MMC module will be 192MHz.
At this frequency, the maximum obtainable timeout (DTO =0xE)
in hardware is (1/192MHz)*2^27 = 700ms. Commands taking longer
than 700ms will be affected by this small window frame and
will be timing out frequently even without a genune timeout
from the card. Workarround for this errata is use a software
timer instead of hardware timer to provide the delay requested
by the upper layer

So adding a software timer as a work around for the errata.
Instead of using software timeout only for larger delays requested
when using HS200/SDR104 cards which results in hardware and
software timer race conditions, so move all the timeout request
to use software timer when HS200/SDR104 card is connected and
use hardware timer when other type cards are connected.

Also start the software timer after queueing to DMA to ensure
we are more likely to expire within correct limits. To be ever
more sure that we won't expire this soft timer too early, we're
adding a 1000000ns slack to the data timeout requested by the
upper layer.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/omap_hsmmc.c |   71 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 6b02c7c..3a02f86 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -168,6 +168,7 @@
 #define ACNE	(1 << 0)
 
 #define MMC_AUTOSUSPEND_DELAY	100
+#define MMC_SOFT_TIMER_SLACK	1000000		/* ns */
 #define MMC_TIMEOUT_MS		20		/* 20 mSec */
 #define MMC_TIMEOUT_US		20000		/* 20000 micro Sec */
 #define OMAP_MMC_MIN_CLOCK	400000
@@ -245,6 +246,10 @@ struct omap_hsmmc_host {
 	struct omap_hsmmc_next	next_data;
 	struct	omap_hsmmc_platform_data	*pdata;
 
+	struct timer_list	timer;
+	unsigned long		data_timeout;
+	unsigned int		need_i834_errata:1;
+
 	u32			*tuning_data;
 	int			tuning_size;
 
@@ -661,8 +666,8 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
 		irq_mask &= ~(BRR_EN | BWR_EN);
 	}
 
-	/* Disable timeout for erases */
-	if (cmd->opcode == MMC_ERASE)
+	/* Disable timeout for erases or when using software timeout */
+	if (cmd->opcode == MMC_ERASE || host->need_i834_errata)
 		irq_mask &= ~DTO_EN;
 
 	spin_lock_irqsave(&host->irq_lock, flags);
@@ -752,6 +757,22 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
 		OMAP_HSMMC_WRITE(host->base, HCTL, regval);
 	}
 
+	/*
+	 * DRA7 Errata No i834: When using high speed HS200 and SDR104
+	 * cards, the functional clock for MMC module will be 192MHz.
+	 * At this frequency, the maximum obtainable timeout (DTO =0xE)
+	 * in hardware is (1/192MHz)*2^27 = 700ms. Commands taking longer
+	 * than 700ms will be affected by this small window frame and
+	 * will be timing out frequently even without a genune timeout
+	 * from the card. Workarround for this errata is use a software
+	 * timer instead of hardware timer to provide the delay requested
+	 * by the upper layer
+	 */
+	if (ios->clock == 192000000)
+		host->need_i834_errata = true;
+	else
+		host->need_i834_errata = false;
+
 	omap_hsmmc_start_clock(host);
 }
 
@@ -1298,6 +1319,16 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
 	int status;
 
 	status = OMAP_HSMMC_READ(host->base, STAT);
+
+	/*
+	 * During a successful bulk data transfer command-completion
+	 * interrupt and transfer-completion interrupt will be generated,
+	 * but software-timeout timer should be deleted only on non-CC
+	 * interrupts (transfer complete or error)
+	 */
+	if (host->need_i834_errata && (status & (~CC_EN)))
+		del_timer(&host->timer);
+
 	while (status & (INT_EN_MASK | CIRQ_EN)) {
 		if (host->req_in_progress)
 			omap_hsmmc_do_irq(host, status);
@@ -1312,6 +1343,13 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static void omap_hsmmc_soft_timeout(unsigned long data)
+{
+	struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)data;
+
+	hsmmc_command_incomplete(host, -ETIMEDOUT, 0);
+}
+
 static void set_sd_bus_power(struct omap_hsmmc_host *host)
 {
 	unsigned long i;
@@ -1513,6 +1551,22 @@ static void set_data_timeout(struct omap_hsmmc_host *host,
 	if (clkd == 0)
 		clkd = 1;
 
+	if (host->need_i834_errata) {
+		unsigned long delta;
+
+		delta = (timeout_clks / (host->clk_rate / clkd));
+
+		/*
+		 * We should really be using just timeout_ns + delta,
+		 * however we have no control over when DMA will
+		 * actually start transferring; due to that we will add
+		 * an extra slack to make sure we don't expire too
+		 * early.
+		 */
+		host->data_timeout = timeout_ns + delta + MMC_SOFT_TIMER_SLACK;
+		return;
+	}
+
 	cycle_ns = 1000000000 / (host->clk_rate / clkd);
 	timeout = timeout_ns / cycle_ns;
 	timeout += timeout_clks;
@@ -1551,6 +1605,13 @@ static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host)
 				req->data->timeout_clks);
 	chan = omap_hsmmc_get_dma_chan(host, req->data);
 	dma_async_issue_pending(chan);
+
+	if (host->need_i834_errata) {
+		unsigned long timeout;
+
+		timeout = jiffies + nsecs_to_jiffies(host->data_timeout);
+		mod_timer(&host->timer, timeout);
+	}
 }
 
 /*
@@ -2415,6 +2476,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 	spin_lock_init(&host->irq_lock);
 	init_completion(&host->buf_ready);
+	setup_timer(&host->timer, omap_hsmmc_soft_timeout,
+		    (unsigned long)host);
 
 	host->fclk = devm_clk_get(&pdev->dev, "fck");
 	if (IS_ERR(host->fclk)) {
@@ -2608,6 +2671,8 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
 	if (host->rx_chan)
 		dma_release_channel(host->rx_chan);
 
+	del_timer_sync(&host->timer);
+
 	pm_runtime_put_sync(host->dev);
 	pm_runtime_disable(host->dev);
 	device_init_wakeup(&pdev->dev, false);
@@ -2640,6 +2705,8 @@ static int omap_hsmmc_suspend(struct device *dev)
 	if (host->dbclk)
 		clk_disable_unprepare(host->dbclk);
 
+	del_timer_sync(&host->timer);
+
 	pm_runtime_put_sync(host->dev);
 	return 0;
 }
-- 
1.7.9.5

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

* [PATCH 00/11] omap_hsmmc: voltage switching and tuning
  2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
                   ` (10 preceding siblings ...)
  2015-07-30  7:46 ` [PATCH 11/11] mmc: host: omap_hsmmc: add software timer when timeout greater than hardware capablility Kishon Vijay Abraham I
@ 2015-08-05 10:43 ` Tony Lindgren
  2015-08-05 15:00   ` Kishon Vijay Abraham I
  11 siblings, 1 reply; 17+ messages in thread
From: Tony Lindgren @ 2015-08-05 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [150730 00:49]:
> Patch series implements voltage switching and tuning for omap_hsmmc
> driver.
> 
> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.

Your tests are missing omap3?

I suggest you add some omap3 tests in general as otherwise you are
only testing a subset of the driver features and completely missing
things like rutnime PM and save and restore for the deeper idle
states.

Regards,

Ton

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

* [PATCH 00/11] omap_hsmmc: voltage switching and tuning
  2015-08-05 10:43 ` [PATCH 00/11] omap_hsmmc: voltage switching and tuning Tony Lindgren
@ 2015-08-05 15:00   ` Kishon Vijay Abraham I
  2015-08-06  6:48     ` Tony Lindgren
  0 siblings, 1 reply; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-08-05 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wednesday 05 August 2015 04:13 PM, Tony Lindgren wrote:
> * Kishon Vijay Abraham I <kishon@ti.com> [150730 00:49]:
>> Patch series implements voltage switching and tuning for omap_hsmmc
>> driver.
>>
>> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
>> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
> 
> Your tests are missing omap3?

I don't have one at my disposal :-( I'll try to find one and add omap3 tests.
> 
> I suggest you add some omap3 tests in general as otherwise you are
> only testing a subset of the driver features and completely missing
> things like rutnime PM and save and restore for the deeper idle
> states.

yeah, I'll do those tests and re-post the series.

Thanks
Kishon

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

* [PATCH 00/11] omap_hsmmc: voltage switching and tuning
  2015-08-05 15:00   ` Kishon Vijay Abraham I
@ 2015-08-06  6:48     ` Tony Lindgren
  2015-08-07 14:45       ` Kishon Vijay Abraham I
  0 siblings, 1 reply; 17+ messages in thread
From: Tony Lindgren @ 2015-08-06  6:48 UTC (permalink / raw)
  To: linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [150805 08:03]:
> Hi,
> 
> On Wednesday 05 August 2015 04:13 PM, Tony Lindgren wrote:
> > * Kishon Vijay Abraham I <kishon@ti.com> [150730 00:49]:
> >> Patch series implements voltage switching and tuning for omap_hsmmc
> >> driver.
> >>
> >> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
> >> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
> > 
> > Your tests are missing omap3?
> 
> I don't have one at my disposal :-( I'll try to find one and add omap3 tests.

Great :) Beagle xm is a good one to test the USB PHY stuff on
and also MMC. Having USB cable connected or EHCI loaded blocks the PM
though, so NFSroot is not very usable for testing on it.

If you want to test PM over NFSroot, boards with the smsc911x known
to work with PM  are at least omap3-evm-37xx.dts and
logicpd-torpedo-37xx-devkit.dts.  Since you tinker with the USB PHYs,
torpedo has MUSB working the same way as the beagle boards, EVM I
think can be modified that way but by default has diffent PHY.

Also overo tobi boards work with PM but only for retntion idle and
not off idle, and map3-sbc-t3517.dts probably can be made to work
with PM but I have mine as a gateway and have not been able to test
with it.

Probably also zoom3 boards with later processor boards can be made
to work, the LDP has early omap34xx variants and can't be made to
work reliably.

I don't have omap3-lilly, but I'd assume that can also be made
to work with PM if not already working.

> > I suggest you add some omap3 tests in general as otherwise you are
> > only testing a subset of the driver features and completely missing
> > things like rutnime PM and save and restore for the deeper idle
> > states.
> 
> yeah, I'll do those tests and re-post the series.

Thanks!

Tony

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

* [PATCH 00/11] omap_hsmmc: voltage switching and tuning
  2015-08-06  6:48     ` Tony Lindgren
@ 2015-08-07 14:45       ` Kishon Vijay Abraham I
  2015-08-11 10:40         ` Tony Lindgren
  0 siblings, 1 reply; 17+ messages in thread
From: Kishon Vijay Abraham I @ 2015-08-07 14:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Thursday 06 August 2015 12:18 PM, Tony Lindgren wrote:
> * Kishon Vijay Abraham I <kishon@ti.com> [150805 08:03]:
>> Hi,
>>
>> On Wednesday 05 August 2015 04:13 PM, Tony Lindgren wrote:
>>> * Kishon Vijay Abraham I <kishon@ti.com> [150730 00:49]:
>>>> Patch series implements voltage switching and tuning for omap_hsmmc
>>>> driver.
>>>>
>>>> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
>>>> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
>>>
>>> Your tests are missing omap3?
>>
>> I don't have one at my disposal :-( I'll try to find one and add omap3 tests.
> 
> Great :) Beagle xm is a good one to test the USB PHY stuff on
> and also MMC. Having USB cable connected or EHCI loaded blocks the PM
> though, so NFSroot is not very usable for testing on it.

I found a beagle xm. So I should be able to get back to this early next week.

Thanks
Kishon
> 
> If you want to test PM over NFSroot, boards with the smsc911x known
> to work with PM  are at least omap3-evm-37xx.dts and
> logicpd-torpedo-37xx-devkit.dts.  Since you tinker with the USB PHYs,
> torpedo has MUSB working the same way as the beagle boards, EVM I
> think can be modified that way but by default has diffent PHY.
> 
> Also overo tobi boards work with PM but only for retntion idle and
> not off idle, and map3-sbc-t3517.dts probably can be made to work
> with PM but I have mine as a gateway and have not been able to test
> with it.
> 
> Probably also zoom3 boards with later processor boards can be made
> to work, the LDP has early omap34xx variants and can't be made to
> work reliably.
> 
> I don't have omap3-lilly, but I'd assume that can also be made
> to work with PM if not already working.
> 
>>> I suggest you add some omap3 tests in general as otherwise you are
>>> only testing a subset of the driver features and completely missing
>>> things like rutnime PM and save and restore for the deeper idle
>>> states.
>>
>> yeah, I'll do those tests and re-post the series.
> 
> Thanks!
> 
> Tony
> 

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

* [PATCH 00/11] omap_hsmmc: voltage switching and tuning
  2015-08-07 14:45       ` Kishon Vijay Abraham I
@ 2015-08-11 10:40         ` Tony Lindgren
  0 siblings, 0 replies; 17+ messages in thread
From: Tony Lindgren @ 2015-08-11 10:40 UTC (permalink / raw)
  To: linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [150807 07:48]:
> Hi,
> 
> On Thursday 06 August 2015 12:18 PM, Tony Lindgren wrote:
> > * Kishon Vijay Abraham I <kishon@ti.com> [150805 08:03]:
> >> Hi,
> >>
> >> On Wednesday 05 August 2015 04:13 PM, Tony Lindgren wrote:
> >>> * Kishon Vijay Abraham I <kishon@ti.com> [150730 00:49]:
> >>>> Patch series implements voltage switching and tuning for omap_hsmmc
> >>>> driver.
> >>>>
> >>>> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
> >>>> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
> >>>
> >>> Your tests are missing omap3?
> >>
> >> I don't have one at my disposal :-( I'll try to find one and add omap3 tests.
> > 
> > Great :) Beagle xm is a good one to test the USB PHY stuff on
> > and also MMC. Having USB cable connected or EHCI loaded blocks the PM
> > though, so NFSroot is not very usable for testing on it.
> 
> I found a beagle xm. So I should be able to get back to this early next week.

OK great!

Thanks,

Tony

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

end of thread, other threads:[~2015-08-11 10:40 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-30  7:46 [PATCH 00/11] omap_hsmmc: voltage switching and tuning Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 01/11] mmc: host: omap_hsmmc: Support vmmc_aux to switch to 1.8v Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 02/11] mmc: host: omap_hsmmc: separate setting voltage capabilities from bus power Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 03/11] mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by mmc core Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 04/11] mmc: host: omap_hsmmc: add voltage switch support for UHS SD card Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 05/11] mmc: host: omap_hsmmc: set clk rate to the max frequency Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 06/11] mmc: host: omap_hsmmc: set timing in the UHSMS field Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 07/11] mmc: host: omap_hsmmc: add tuning support Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 08/11] mmc: host: omap_hsmmc: Workaround for errata id i802 Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 09/11] mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 10/11] mmc: host: omap_hsmmc: remove incorrect voltage switch sequence Kishon Vijay Abraham I
2015-07-30  7:46 ` [PATCH 11/11] mmc: host: omap_hsmmc: add software timer when timeout greater than hardware capablility Kishon Vijay Abraham I
2015-08-05 10:43 ` [PATCH 00/11] omap_hsmmc: voltage switching and tuning Tony Lindgren
2015-08-05 15:00   ` Kishon Vijay Abraham I
2015-08-06  6:48     ` Tony Lindgren
2015-08-07 14:45       ` Kishon Vijay Abraham I
2015-08-11 10:40         ` Tony Lindgren

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).