{"id":816965,"url":"http://patchwork.ozlabs.org/api/patches/816965/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/1506007346-10037-18-git-send-email-jjhiblot@ti.com/","project":{"id":18,"url":"http://patchwork.ozlabs.org/api/projects/18/?format=json","name":"U-Boot","link_name":"uboot","list_id":"u-boot.lists.denx.de","list_email":"u-boot@lists.denx.de","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<1506007346-10037-18-git-send-email-jjhiblot@ti.com>","list_archive_url":null,"date":"2017-09-21T15:22:20","name":"[U-Boot,17/23] mmc: omap_hsmmc: add signal voltage selection support","commit_ref":null,"pull_url":null,"state":"changes-requested","archived":false,"hash":"a2f51a70d6b5fcafd8bdb6488ac15896910e9a4e","submitter":{"id":70508,"url":"http://patchwork.ozlabs.org/api/people/70508/?format=json","name":"Jean-Jacques Hiblot","email":"jjhiblot@ti.com"},"delegate":{"id":3651,"url":"http://patchwork.ozlabs.org/api/users/3651/?format=json","username":"trini","first_name":"Tom","last_name":"Rini","email":"trini@ti.com"},"mbox":"http://patchwork.ozlabs.org/project/uboot/patch/1506007346-10037-18-git-send-email-jjhiblot@ti.com/mbox/","series":[{"id":4414,"url":"http://patchwork.ozlabs.org/api/series/4414/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/list/?series=4414","date":"2017-09-21T15:22:03","name":"mmc: omap5: Add support for UHS and HS200 modes","version":1,"mbox":"http://patchwork.ozlabs.org/series/4414/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/816965/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/816965/checks/","tags":{},"related":[],"headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.denx.de\n\t(client-ip=81.169.180.215; helo=lists.denx.de;\n\tenvelope-from=u-boot-bounces@lists.denx.de;\n\treceiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ti.com header.i=@ti.com header.b=\"cm+BLgHE\";\n\tdkim-atps=neutral"],"Received":["from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3xygYt4krfz9t4P\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 22 Sep 2017 01:31:11 +1000 (AEST)","by lists.denx.de (Postfix, from userid 105)\n\tid 8FC6BC22096; Thu, 21 Sep 2017 15:25:36 +0000 (UTC)","from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id 70C69C22099;\n\tThu, 21 Sep 2017 15:23:52 +0000 (UTC)","by lists.denx.de (Postfix, from userid 105)\n\tid 3DE12C21F67; Thu, 21 Sep 2017 15:23:07 +0000 (UTC)","from lelnx194.ext.ti.com (lelnx194.ext.ti.com [198.47.27.80])\n\tby lists.denx.de (Postfix) with ESMTPS id 950A7C2204C\n\tfor <u-boot@lists.denx.de>; Thu, 21 Sep 2017 15:23:03 +0000 (UTC)","from dlelxv90.itg.ti.com ([172.17.2.17])\n\tby lelnx194.ext.ti.com (8.15.1/8.15.1) with ESMTP id v8LFN1JW013971; \n\tThu, 21 Sep 2017 10:23:01 -0500","from DFLE105.ent.ti.com (dfle105.ent.ti.com [10.64.6.26])\n\tby dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id v8LFN1RW000728; \n\tThu, 21 Sep 2017 10:23:01 -0500","from DFLE115.ent.ti.com (10.64.6.36) by DFLE105.ent.ti.com\n\t(10.64.6.26) with Microsoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.845.34;\n\tThu, 21 Sep 2017 10:23:01 -0500","from dflp33.itg.ti.com (10.64.6.16) by DFLE115.ent.ti.com\n\t(10.64.6.36) with Microsoft SMTP Server (version=TLS1_0,\n\tcipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.845.34 via Frontend\n\tTransport; Thu, 21 Sep 2017 10:23:01 -0500","from localhost (ileax41-snat.itg.ti.com [10.172.224.153])\n\tby dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id v8LFN0FM023027;\n\tThu, 21 Sep 2017 10:23:00 -0500"],"X-Spam-Checker-Version":"SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=0.0 required=5.0 tests=RCVD_IN_DNSWL_NONE,\n\tT_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ti.com;\n\ts=ti-com-17Q1; t=1506007381;\n\tbh=+j+4jPiNsDkFT0/m/dn/Kb0qlc96b0TbUpARjSOOY2Y=;\n\th=From:To:CC:Subject:Date:In-Reply-To:References;\n\tb=cm+BLgHEoMSlJkWBdxxCzUE+9tr+pBPfRCOG34FKhdvq5pIyABhTyClv84BqEUpGZ\n\tytTC+D0wl5AGbTgDdmjFid0vpAX3C1NRe+pKomsAbr3zSASlZ1u4V/oQLXFClAH1XH\n\tthw4gVXMrfcvWj3oMVj7Z0OJL5iMhaoCxTjA413w=","From":"Jean-Jacques Hiblot <jjhiblot@ti.com>","To":"<jh80.chung@samsung.com>, <trini@konsulko.com>, <kishon@ti.com>,\n\t<sjg@chromium.org>, <lokeshvutla@ti.com>","Date":"Thu, 21 Sep 2017 17:22:20 +0200","Message-ID":"<1506007346-10037-18-git-send-email-jjhiblot@ti.com>","X-Mailer":"git-send-email 1.9.1","In-Reply-To":"<1506007346-10037-1-git-send-email-jjhiblot@ti.com>","References":"<1506007346-10037-1-git-send-email-jjhiblot@ti.com>","MIME-Version":"1.0","X-EXCLAIMER-MD-CONFIG":"e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180","Cc":"u-boot@lists.denx.de","Subject":"[U-Boot] [PATCH 17/23] mmc: omap_hsmmc: add signal voltage\n\tselection support","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.18","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<http://lists.denx.de/pipermail/u-boot/>","List-Post":"<mailto:u-boot@lists.denx.de>","List-Help":"<mailto:u-boot-request@lists.denx.de?subject=help>","List-Subscribe":"<https://lists.denx.de/listinfo/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=subscribe>","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>"},"content":"I/O data lines of UHS SD card operates at 1.8V when in UHS speed\nmode (same is true for eMMC in DDR and HS200 modes). Add support\nto switch signal voltage to 1.8V in order to support\nUHS cards and eMMC HS200 and DDR modes.\n\nSigned-off-by: Kishon Vijay Abraham I <kishon@ti.com>\nSigned-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>\n---\n arch/arm/include/asm/omap_mmc.h |  10 ++-\n drivers/mmc/omap_hsmmc.c        | 162 +++++++++++++++++++++++++++++++++++-----\n 2 files changed, 151 insertions(+), 21 deletions(-)","diff":"diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h\nindex 3073805..6871f54 100644\n--- a/arch/arm/include/asm/omap_mmc.h\n+++ b/arch/arm/include/asm/omap_mmc.h\n@@ -172,10 +172,6 @@ struct omap_hsmmc_plat {\n #define VS30_3V0SUP\t\t\tBIT(25)\n #define VS18_1V8SUP\t\t\tBIT(26)\n \n-#define IOV_3V3\t\t\t\t3300000\n-#define IOV_3V0\t\t\t\t3000000\n-#define IOV_1V8\t\t\t\t1800000\n-\n #define AC12_ET\t\t\t\t(1 << 22)\n #define AC12_V1V8_SIGEN\t\t(1 << 19)\n #define AC12_SCLK_SEL\t\t(1 << 23)\n@@ -224,6 +220,12 @@ struct omap_hsmmc_plat {\n \t\tIE_DTO | IE_CIE | IE_CEB | IE_CCRC | IE_ADMAE | IE_CTO |\\\n \t\tIE_BRR | IE_BWR | IE_TC | IE_CC)\n \n+#define CON_CLKEXTFREE\t\tBIT(16)\n+#define CON_PADEN\t\tBIT(15)\n+#define PSTATE_CLEV\t\tBIT(24)\n+#define PSTATE_DLEV\t\t(0xF << 20)\n+#define PSTATE_DLEV_DAT0\t(0x1 << 20)\n+\n int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,\n \t\tint wp_gpio);\n \ndiff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c\nindex f3da446..ecf5171 100644\n--- a/drivers/mmc/omap_hsmmc.c\n+++ b/drivers/mmc/omap_hsmmc.c\n@@ -78,6 +78,7 @@ struct omap_hsmmc_data {\n #endif\n \tuint bus_width;\n \tuint clock;\n+\tushort last_cmd;\n #ifdef OMAP_HSMMC_USE_GPIO\n #if CONFIG_IS_ENABLED(DM_MMC)\n \tstruct gpio_desc cd_gpio;\t/* Change Detect GPIO */\n@@ -89,7 +90,6 @@ struct omap_hsmmc_data {\n #endif\n #endif\n #if CONFIG_IS_ENABLED(DM_MMC)\n-\tuint iov;\n \tenum bus_mode mode;\n #endif\n \tu8 controller_flags;\n@@ -98,6 +98,8 @@ struct omap_hsmmc_data {\n \tuint desc_slot;\n #endif\n \tconst char *hw_rev;\n+\tstruct udevice *pbias_supply;\n+\tuint signal_voltage;\n #ifdef CONFIG_IODELAY_RECALIBRATION\n \tstruct omap_hsmmc_pinctrl_state *default_pinctrl_state;\n \tstruct omap_hsmmc_pinctrl_state *hs_pinctrl_state;\n@@ -254,7 +256,8 @@ static unsigned char mmc_board_init(struct mmc *mmc)\n \t\t&prcm_base->iclken1_core);\n #endif\n \n-#if defined(CONFIG_OMAP54XX) || defined(CONFIG_OMAP44XX)\n+#if (defined(CONFIG_OMAP54XX) || defined(CONFIG_OMAP44XX)) &&\\\n+\t!CONFIG_IS_ENABLED(DM_REGULATOR)\n \t/* PBIAS config needed for MMC1 only */\n \tif (mmc_get_blk_desc(mmc)->devnum == 0)\n \t\tvmmc_pbias_config(LDO_VOLT_3V0);\n@@ -398,7 +401,7 @@ static void omap_hsmmc_set_timing(struct mmc *mmc)\n \tomap_hsmmc_start_clock(mmc_base);\n }\n \n-static void omap_hsmmc_conf_bus_power(struct mmc *mmc)\n+static void omap_hsmmc_conf_bus_power(struct mmc *mmc, uint signal_voltage)\n {\n \tstruct hsmmc *mmc_base;\n \tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n@@ -408,14 +411,11 @@ static void omap_hsmmc_conf_bus_power(struct mmc *mmc)\n \n \tval = readl(&mmc_base->hctl) & ~SDVS_MASK;\n \n-\tswitch (priv->iov) {\n-\tcase IOV_3V3:\n-\t\tval |= SDVS_3V3;\n-\t\tbreak;\n-\tcase IOV_3V0:\n+\tswitch (signal_voltage) {\n+\tcase MMC_SIGNAL_VOLTAGE_330:\n \t\tval |= SDVS_3V0;\n \t\tbreak;\n-\tcase IOV_1V8:\n+\tcase MMC_SIGNAL_VOLTAGE_180:\n \t\tval |= SDVS_1V8;\n \t\tbreak;\n \t}\n@@ -423,7 +423,126 @@ static void omap_hsmmc_conf_bus_power(struct mmc *mmc)\n \twritel(val, &mmc_base->hctl);\n }\n \n-static void omap_hsmmc_set_capabilities(struct mmc *mmc)\n+static int omap_hsmmc_wait_dat0(struct udevice *dev, int state, int timeout)\n+{\n+\tint ret = -ETIMEDOUT;\n+\tu32 con;\n+\tbool dat0_high;\n+\tbool target_dat0_high = !!state;\n+\tstruct omap_hsmmc_data *priv = dev_get_priv(dev);\n+\tstruct hsmmc *mmc_base = priv->base_addr;\n+\n+\tcon = readl(&mmc_base->con);\n+\twritel(con | CON_CLKEXTFREE | CON_PADEN, &mmc_base->con);\n+\n+\ttimeout = DIV_ROUND_UP(timeout, 10); /* check every 10 us. */\n+\twhile (timeout--)\t{\n+\t\tdat0_high = !!(readl(&mmc_base->pstate) & PSTATE_DLEV_DAT0);\n+\t\tif (dat0_high == target_dat0_high) {\n+\t\t\tret = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t\tudelay(10);\n+\t}\n+\twritel(con, &mmc_base->con);\n+\n+\treturn ret;\n+}\n+\n+#if CONFIG_IS_ENABLED(DM_REGULATOR)\n+static int omap_hsmmc_set_io_regulator(struct mmc *mmc, int mV)\n+{\n+\tint ret = 0;\n+\tint uV = mV * 1000;\n+\n+\tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n+\n+\tif (!mmc->vqmmc_supply)\n+\t\treturn 0;\n+\n+\t/* Disable PBIAS */\n+\tret = regulator_set_enable(priv->pbias_supply, false);\n+\tif (ret && ret != -ENOSYS)\n+\t\treturn ret;\n+\n+\t/* Turn off IO voltage */\n+\tret = regulator_set_enable(mmc->vqmmc_supply, false);\n+\tif (ret && ret != -ENOSYS)\n+\t\treturn ret;\n+\t/* Program a new IO voltage value */\n+\tret = regulator_set_value(mmc->vqmmc_supply, uV);\n+\tif (ret)\n+\t\treturn ret;\n+\t/* Turn on IO voltage */\n+\tret = regulator_set_enable(mmc->vqmmc_supply, true);\n+\tif (ret && ret != -ENOSYS)\n+\t\treturn ret;\n+\n+\t/* Program PBIAS voltage*/\n+\tret = regulator_set_value(priv->pbias_supply, uV);\n+\tif (ret && ret != -ENOSYS)\n+\t\treturn ret;\n+\t/* Enable PBIAS */\n+\tret = regulator_set_enable(priv->pbias_supply, true);\n+\tif (ret && ret != -ENOSYS)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+#endif\n+\n+static int omap_hsmmc_set_signal_voltage(struct mmc *mmc)\n+{\n+\tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n+\tstruct hsmmc *mmc_base = priv->base_addr;\n+\tint mv = mmc_voltage_to_mv(mmc->signal_voltage);\n+\tu32 capa_mask;\n+\tu32 ac12_v1v8;\n+\t__maybe_unused u8 palmas_ldo_volt;\n+\tu32 val;\n+\n+\tif (mv < 0)\n+\t\treturn -EINVAL;\n+\n+\tif (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {\n+\t\t/* Use 3.0V rather than 3.3V */\n+\t\tmv = 3000;\n+\t\tcapa_mask = VS30_3V0SUP;\n+\t\tac12_v1v8 = 0;\n+\t\tpalmas_ldo_volt = LDO_VOLT_3V0;\n+\t} else if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {\n+\t\tcapa_mask = VS18_1V8SUP;\n+\t\tac12_v1v8 = AC12_V1V8_SIGEN;\n+\t\tpalmas_ldo_volt = LDO_VOLT_1V8;\n+\t} else {\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tval = readl(&mmc_base->capa);\n+\tif (!(val & capa_mask))\n+\t\treturn -EOPNOTSUPP;\n+\n+\tpriv->signal_voltage = mmc->signal_voltage;\n+\n+\tomap_hsmmc_conf_bus_power(mmc, mmc->signal_voltage);\n+\n+\tval = readl(&mmc_base->ac12);\n+\tval = (val & ~AC12_V1V8_SIGEN) | ac12_v1v8;\n+\twritel(val, &mmc_base->ac12);\n+\n+#if CONFIG_IS_ENABLED(DM_REGULATOR)\n+\treturn omap_hsmmc_set_io_regulator(mmc, mv);\n+#elif (defined(CONFIG_OMAP54XX) || defined(CONFIG_OMAP44XX)) && \\\n+\tdefined(CONFIG_PALMAS_POWER)\n+\tif (mmc_get_blk_desc(mmc)->devnum == 0)\n+\t\tvmmc_pbias_config(palmas_ldo_volt);\n+\treturn 0;\n+#else\n+\treturn 0;\n+#endif\n+}\n+\n+static uint32_t omap_hsmmc_set_capabilities(struct mmc *mmc)\n {\n \tstruct hsmmc *mmc_base;\n \tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n@@ -434,18 +553,17 @@ static void omap_hsmmc_set_capabilities(struct mmc *mmc)\n \n \tif (priv->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {\n \t\tval |= (VS30_3V0SUP | VS18_1V8SUP);\n-\t\tpriv->iov = IOV_3V0;\n \t} else if (priv->controller_flags & OMAP_HSMMC_NO_1_8_V) {\n \t\tval |= VS30_3V0SUP;\n \t\tval &= ~VS18_1V8SUP;\n-\t\tpriv->iov = IOV_3V0;\n \t} else {\n \t\tval |= VS18_1V8SUP;\n \t\tval &= ~VS30_3V0SUP;\n-\t\tpriv->iov = IOV_1V8;\n \t}\n \n \twritel(val, &mmc_base->capa);\n+\n+\treturn val;\n }\n \n static void omap_hsmmc_disable_tuning(struct mmc *mmc)\n@@ -628,8 +746,9 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)\n #endif\n \n #if CONFIG_IS_ENABLED(DM_MMC)\n-\tomap_hsmmc_set_capabilities(mmc);\n-\tomap_hsmmc_conf_bus_power(mmc);\n+\treg_val = omap_hsmmc_set_capabilities(mmc);\n+\tomap_hsmmc_conf_bus_power(mmc, (reg_val & VS30_3V0SUP) ?\n+\t\t\t  MMC_SIGNAL_VOLTAGE_330 : MMC_SIGNAL_VOLTAGE_180);\n #else\n \twritel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);\n \twritel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,\n@@ -840,6 +959,7 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,\n \tstruct hsmmc *mmc_base;\n \tunsigned int flags, mmc_stat;\n \tulong start;\n+\tpriv->last_cmd = cmd->cmdidx;\n \n \tmmc_base = priv->base_addr;\n \n@@ -1204,6 +1324,7 @@ static int omap_hsmmc_set_ios(struct udevice *dev)\n \tstruct mmc *mmc = upriv->mmc;\n #endif\n \tstruct hsmmc *mmc_base = priv->base_addr;\n+\tint ret = 0;\n \n \tif (priv->bus_width != mmc->bus_width)\n \t\tomap_hsmmc_set_bus_width(mmc);\n@@ -1219,8 +1340,11 @@ static int omap_hsmmc_set_ios(struct udevice *dev)\n #if CONFIG_IS_ENABLED(DM_MMC)\n \tif (priv->mode != mmc->selected_mode)\n \t\tomap_hsmmc_set_timing(mmc);\n+\n+\tif (priv->signal_voltage != mmc->signal_voltage)\n+\t\tret = omap_hsmmc_set_signal_voltage(mmc);\n #endif\n-\treturn 0;\n+\treturn ret;\n }\n \n #ifdef OMAP_HSMMC_USE_GPIO\n@@ -1292,6 +1416,7 @@ static const struct dm_mmc_ops omap_hsmmc_ops = {\n #endif\n \t.execute_tuning = omap_hsmmc_execute_tuning,\n \t.send_init_stream\t= omap_hsmmc_send_init_stream,\n+\t.wait_dat0\t= omap_hsmmc_wait_dat0,\n };\n #else\n static const struct mmc_ops omap_hsmmc_ops = {\n@@ -1753,7 +1878,10 @@ static int omap_hsmmc_probe(struct udevice *dev)\n \tif (mmc == NULL)\n \t\treturn -1;\n #endif\n-\n+#if CONFIG_IS_ENABLED(DM_REGULATOR)\n+\tdevice_get_supply_regulator(dev, \"pbias-supply\",\n+\t\t\t\t    &priv->pbias_supply);\n+#endif\n #if defined(OMAP_HSMMC_USE_GPIO) && CONFIG_IS_ENABLED(OF_CONTROL)\n \tgpio_request_by_name(dev, \"cd-gpios\", 0, &priv->cd_gpio, GPIOD_IS_IN);\n \tgpio_request_by_name(dev, \"wp-gpios\", 0, &priv->wp_gpio, GPIOD_IS_IN);\n","prefixes":["U-Boot","17/23"]}