{"id":816974,"url":"http://patchwork.ozlabs.org/api/patches/816974/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/1506007346-10037-7-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-7-git-send-email-jjhiblot@ti.com>","list_archive_url":null,"date":"2017-09-21T15:22:09","name":"[U-Boot,06/23] mmc: omap_hsmmc: Add tuning support","commit_ref":null,"pull_url":null,"state":"changes-requested","archived":false,"hash":"21b17e355756cccb593c4ca2483fc116e493bf80","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-7-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/816974/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/816974/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=\"o2DpegYt\";\n\tdkim-atps=neutral"],"Received":["from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3xygfN5cgBz9s06\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 22 Sep 2017 01:35:08 +1000 (AEST)","by lists.denx.de (Postfix, from userid 105)\n\tid 92A19C220FC; Thu, 21 Sep 2017 15:28:49 +0000 (UTC)","from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id C458BC220B6;\n\tThu, 21 Sep 2017 15:28:46 +0000 (UTC)","by lists.denx.de (Postfix, from userid 105)\n\tid 64F2CC22091; Thu, 21 Sep 2017 15:23:58 +0000 (UTC)","from fllnx209.ext.ti.com (fllnx209.ext.ti.com [198.47.19.16])\n\tby lists.denx.de (Postfix) with ESMTPS id B588FC2205D\n\tfor <u-boot@lists.denx.de>; Thu, 21 Sep 2017 15:23:54 +0000 (UTC)","from dlelxv90.itg.ti.com ([172.17.2.17])\n\tby fllnx209.ext.ti.com (8.15.1/8.15.1) with ESMTP id v8LFMqJs009127; \n\tThu, 21 Sep 2017 10:22:52 -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 v8LFMlGi032760; \n\tThu, 21 Sep 2017 10:22:47 -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:22:47 -0500","from dflp32.itg.ti.com (10.64.6.15) 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:22:47 -0500","from localhost (ileax41-snat.itg.ti.com [10.172.224.153])\n\tby dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id v8LFMkwu014784;\n\tThu, 21 Sep 2017 10:22:46 -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=1506007372;\n\tbh=Ucm4lqVe13YFtZDnIHUxkESLqTrwu2lHDaw+tuZA0E0=;\n\th=From:To:CC:Subject:Date:In-Reply-To:References;\n\tb=o2DpegYtAZk9FpPc9IeOyf/ObvbguEz+0GJT0kLWODSHCGeUQ46eoWNeCrdM/TCV8\n\tvUQUR2ADufoB3a2oIih5eCHSMZpp9ID9Om9ySGrLKR2KS9SWjffOv0Sn5v7NtK36U/\n\tSNVYwwrrz7J6zGlnjKpnpazbrDWruCQL8Pi3r6Fw=","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:09 +0200","Message-ID":"<1506007346-10037-7-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 06/23] mmc: omap_hsmmc: Add tuning 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":"From: Kishon Vijay Abraham I <kishon@ti.com>\n\nHS200/SDR104 requires tuning command to be sent to the card. Use\nthe mmc_send_tuning library function to send the tuning\ncommand and configure the internal DLL.\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 |  21 ++++++-\n drivers/mmc/omap_hsmmc.c        | 118 ++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 137 insertions(+), 2 deletions(-)","diff":"diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h\nindex 341a2e2..0293281 100644\n--- a/arch/arm/include/asm/omap_mmc.h\n+++ b/arch/arm/include/asm/omap_mmc.h\n@@ -39,7 +39,9 @@ struct hsmmc {\n \tunsigned int sysstatus;\t\t/* 0x14 */\n \tunsigned char res2[0x14];\n \tunsigned int con;\t\t/* 0x2C */\n-\tunsigned char res3[0xD4];\n+\tunsigned int pwcnt;\t\t/* 0x30 */\n+\tunsigned int dll;\t\t/* 0x34 */\n+\tunsigned char res3[0xcc];\n \tunsigned int blk;\t\t/* 0x104 */\n \tunsigned int arg;\t\t/* 0x108 */\n \tunsigned int cmd;\t\t/* 0x10C */\n@@ -56,7 +58,8 @@ struct hsmmc {\n \tunsigned char res4[0x4];\n \tunsigned int ac12;\t\t/* 0x13C */\n \tunsigned int capa;\t\t/* 0x140 */\n-\tunsigned char res5[0x10];\n+\tunsigned int capa2;\t\t/* 0x144 */\n+\tunsigned char res5[0xc];\n \tunsigned int admaes;\t\t/* 0x154 */\n \tunsigned int admasal;\t\t/* 0x158 */\n };\n@@ -173,6 +176,8 @@ struct omap_hsmmc_plat {\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 #define AC12_UHSMC_MASK\t\t\t(7 << 16)\n #define AC12_UHSMC_DDR50\t\t(4 << 16)\n #define AC12_UHSMC_SDR104\t\t(3 << 16)\n@@ -199,6 +204,18 @@ struct omap_hsmmc_plat {\n /* Clock Configurations and Macros */\n #define MMC_CLOCK_REFERENCE\t96 /* MHz */\n \n+/* DLL */\n+#define DLL_SWT\t\t\t(1 << 20)\n+#define DLL_FORCE_SR_C_SHIFT\t13\n+#define DLL_FORCE_SR_C_MASK\t0x7f\n+#define DLL_FORCE_VALUE\t\t(1 << 12)\n+#define DLL_CALIB\t\t(1 << 1)\n+\n+#define MAX_PHASE_DELAY\t\t0x7c\n+\n+/* CAPA2 */\n+#define CAPA2_TSDR50\t\t(1 << 13)\n+\n #define mmc_reg_out(addr, mask, val)\\\n \twritel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))\n \ndiff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c\nindex d5cd826..321a091 100644\n--- a/drivers/mmc/omap_hsmmc.c\n+++ b/drivers/mmc/omap_hsmmc.c\n@@ -124,6 +124,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,\n \t\t\tunsigned int siz);\n static void omap_hsmmc_start_clock(struct hsmmc *mmc_base);\n static void omap_hsmmc_stop_clock(struct hsmmc *mmc_base);\n+static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit);\n \n static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)\n {\n@@ -355,6 +356,122 @@ static void omap_hsmmc_set_capabilities(struct mmc *mmc)\n \n \twritel(val, &mmc_base->capa);\n }\n+\n+static void omap_hsmmc_disable_tuning(struct mmc *mmc)\n+{\n+\tstruct hsmmc *mmc_base;\n+\tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n+\tu32 val;\n+\n+\tmmc_base = priv->base_addr;\n+\tval = readl(&mmc_base->ac12);\n+\tval &= ~(AC12_SCLK_SEL);\n+\twritel(val, &mmc_base->ac12);\n+\n+\tval = readl(&mmc_base->dll);\n+\tval &= ~(DLL_FORCE_VALUE | DLL_SWT);\n+\twritel(val, &mmc_base->dll);\n+}\n+\n+static void omap_hsmmc_set_dll(struct mmc *mmc, int count)\n+{\n+\tint i;\n+\tstruct hsmmc *mmc_base;\n+\tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n+\tu32 val;\n+\n+\tmmc_base = priv->base_addr;\n+\tval = readl(&mmc_base->dll);\n+\tval |= DLL_FORCE_VALUE;\n+\tval &= ~(DLL_FORCE_SR_C_MASK << DLL_FORCE_SR_C_SHIFT);\n+\tval |= (count << DLL_FORCE_SR_C_SHIFT);\n+\twritel(val, &mmc_base->dll);\n+\n+\tval |= DLL_CALIB;\n+\twritel(val, &mmc_base->dll);\n+\tfor (i = 0; i < 1000; i++) {\n+\t\tif (readl(&mmc_base->dll) & DLL_CALIB)\n+\t\t\tbreak;\n+\t}\n+\tval &= ~DLL_CALIB;\n+\twritel(val, &mmc_base->dll);\n+}\n+\n+static int omap_hsmmc_execute_tuning(struct udevice *dev, uint opcode)\n+{\n+\tstruct omap_hsmmc_data *priv = dev_get_priv(dev);\n+\tstruct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);\n+\tstruct mmc *mmc = upriv->mmc;\n+\tstruct hsmmc *mmc_base;\n+\tu32 val;\n+\tu8 cur_match, prev_match = 0;\n+\tint ret;\n+\tu32 phase_delay = 0;\n+\tu32 start_window = 0, max_window = 0;\n+\tu32 length = 0, max_len = 0;\n+\n+\tmmc_base = priv->base_addr;\n+\tval = readl(&mmc_base->capa2);\n+\n+\t/* clock tuning is not needed for upto 52MHz */\n+\tif (!((mmc->selected_mode == MMC_HS_200) ||\n+\t      (mmc->selected_mode == UHS_SDR104) ||\n+\t      ((mmc->selected_mode == UHS_SDR50) && (val & CAPA2_TSDR50))))\n+\t\treturn 0;\n+\n+\tval = readl(&mmc_base->dll);\n+\tval |= DLL_SWT;\n+\twritel(val, &mmc_base->dll);\n+\twhile (phase_delay <= MAX_PHASE_DELAY) {\n+\t\tomap_hsmmc_set_dll(mmc, phase_delay);\n+\n+\t\tcur_match = !mmc_send_tuning(mmc, opcode, NULL);\n+\n+\t\tif (cur_match) {\n+\t\t\tif (prev_match) {\n+\t\t\t\tlength++;\n+\t\t\t} else {\n+\t\t\t\tstart_window = phase_delay;\n+\t\t\t\tlength = 1;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (length > max_len) {\n+\t\t\tmax_window = start_window;\n+\t\t\tmax_len = length;\n+\t\t}\n+\n+\t\tprev_match = cur_match;\n+\t\tphase_delay += 4;\n+\t}\n+\n+\tif (!max_len) {\n+\t\tret = -EIO;\n+\t\tgoto tuning_error;\n+\t}\n+\n+\tval = readl(&mmc_base->ac12);\n+\tif (!(val & AC12_SCLK_SEL)) {\n+\t\tret = -EIO;\n+\t\tgoto tuning_error;\n+\t}\n+\n+\tphase_delay = max_window + 4 * ((3 * max_len) >> 2);\n+\tomap_hsmmc_set_dll(mmc, phase_delay);\n+\n+\tmmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);\n+\tmmc_reset_controller_fsm(mmc_base, SYSCTL_SRC);\n+\n+\treturn 0;\n+\n+tuning_error:\n+\n+\tomap_hsmmc_disable_tuning(mmc);\n+\tmmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);\n+\tmmc_reset_controller_fsm(mmc_base, SYSCTL_SRC);\n+\n+\treturn ret;\n+}\n #endif\n \n static int omap_hsmmc_init_setup(struct mmc *mmc)\n@@ -1046,6 +1163,7 @@ static const struct dm_mmc_ops omap_hsmmc_ops = {\n \t.get_cd\t\t= omap_hsmmc_getcd,\n \t.get_wp\t\t= omap_hsmmc_getwp,\n #endif\n+\t.execute_tuning = omap_hsmmc_execute_tuning,\n };\n #else\n static const struct mmc_ops omap_hsmmc_ops = {\n","prefixes":["U-Boot","06/23"]}