{"id":816926,"url":"http://patchwork.ozlabs.org/api/patches/816926/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/1506005496-8635-4-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":"<1506005496-8635-4-git-send-email-jjhiblot@ti.com>","list_archive_url":null,"date":"2017-09-21T14:51:34","name":"[U-Boot,v2,3/5] mmc: omap_hsmmc: Add support for DMA (ADMA2)","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"40f76f5b4ba0da3d6f2b8f797620f1af3e322637","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/1506005496-8635-4-git-send-email-jjhiblot@ti.com/mbox/","series":[{"id":4406,"url":"http://patchwork.ozlabs.org/api/series/4406/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/list/?series=4406","date":"2017-09-21T14:51:31","name":"mmc: omap_hsmmc: Add support for ADMA","version":2,"mbox":"http://patchwork.ozlabs.org/series/4406/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/816926/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/816926/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=\"aU4m6LLh\";\n\tdkim-atps=neutral"],"Received":["from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3xyfjg4zQnz9t3w\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 22 Sep 2017 00:52:55 +1000 (AEST)","by lists.denx.de (Postfix, from userid 105)\n\tid 78DEAC22067; Thu, 21 Sep 2017 14:52:18 +0000 (UTC)","from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id 99C6EC2205A;\n\tThu, 21 Sep 2017 14:52:14 +0000 (UTC)","by lists.denx.de (Postfix, from userid 105)\n\tid 757A9C22062; Thu, 21 Sep 2017 14:51:58 +0000 (UTC)","from lelnx194.ext.ti.com (lelnx194.ext.ti.com [198.47.27.80])\n\tby lists.denx.de (Postfix) with ESMTPS id 7B534C2200B\n\tfor <u-boot@lists.denx.de>; Thu, 21 Sep 2017 14:51:55 +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 v8LEprua007898; \n\tThu, 21 Sep 2017 09:51:53 -0500","from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25])\n\tby dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id v8LEpr8O019616; \n\tThu, 21 Sep 2017 09:51:53 -0500","from DFLE115.ent.ti.com (10.64.6.36) by DFLE104.ent.ti.com\n\t(10.64.6.25) 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 09:51:53 -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 09:51:53 -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 v8LEppr6022202;\n\tThu, 21 Sep 2017 09:51:52 -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=1506005513;\n\tbh=mYNad7hAHpUYwuf59LDjsC/2LBlYNOq0Kg4UBERJVRA=;\n\th=From:To:CC:Subject:Date:In-Reply-To:References;\n\tb=aU4m6LLhCkQVOSyFopKIJN0XaI4yOm2Cp0urFf8EQcIW5ETdUfxNGHLgKTbfckLWO\n\tVpiGhtl5KiqV7CfQ5aHh90haUVY+J4S4TeMC7tMoP8g03gTDctrZP/0OOLFLfPD/oo\n\tZD587Et88+HTYtCNFVFcA4/vbHZxLN7Zx1bb6rsI=","From":"Jean-Jacques Hiblot <jjhiblot@ti.com>","To":"<jh80.chung@samsung.com>, <trini@konsulko.com>, <kishon@ti.com>,\n\t<sjg@chromium.org>","Date":"Thu, 21 Sep 2017 16:51:34 +0200","Message-ID":"<1506005496-8635-4-git-send-email-jjhiblot@ti.com>","X-Mailer":"git-send-email 1.9.1","In-Reply-To":"<1506005496-8635-1-git-send-email-jjhiblot@ti.com>","References":"<1506005496-8635-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 v2 3/5] mmc: omap_hsmmc: Add support for DMA (ADMA2)","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\nThe omap hsmmc host controller can have the ADMA2 feature. It brings better\nread and write throughput.\nOn most SOC, the capability is read from the hl_hwinfo register. On OMAP3,\nDMA support is compiled out.\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 |  12 ++-\n drivers/mmc/omap_hsmmc.c        | 203 +++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 211 insertions(+), 4 deletions(-)","diff":"diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h\nindex 77278a3..128cd81 100644\n--- a/arch/arm/include/asm/omap_mmc.h\n+++ b/arch/arm/include/asm/omap_mmc.h\n@@ -29,7 +29,10 @@\n \n struct hsmmc {\n #ifndef CONFIG_OMAP34XX\n-\tunsigned char res0[0x100];\n+\tunsigned int hl_rev;\n+\tunsigned int hl_hwinfo;\n+\tunsigned int hl_sysconfig;\n+\tunsigned char res0[0xf4];\n #endif\n \tunsigned char res1[0x10];\n \tunsigned int sysconfig;\t\t/* 0x10 */\n@@ -52,6 +55,9 @@ struct hsmmc {\n \tunsigned int ie;\t\t/* 0x134 */\n \tunsigned char res4[0x8];\n \tunsigned int capa;\t\t/* 0x140 */\n+\tunsigned char res5[0x10];\n+\tunsigned int admaes;\t\t/* 0x154 */\n+\tunsigned int admasal;\t\t/* 0x158 */\n };\n \n struct omap_hsmmc_plat {\n@@ -64,6 +70,7 @@ struct omap_hsmmc_plat {\n /*\n  * OMAP HS MMC Bit definitions\n  */\n+#define MADMA_EN\t\t\t(0x1 << 0)\n #define MMC_SOFTRESET\t\t\t(0x1 << 1)\n #define RESETDONE\t\t\t(0x1 << 0)\n #define NOOPENDRAIN\t\t\t(0x0 << 0)\n@@ -80,6 +87,7 @@ struct omap_hsmmc_plat {\n #define WPP_ACTIVEHIGH\t\t\t(0x0 << 8)\n #define RESERVED_MASK\t\t\t(0x3 << 9)\n #define CTPL_MMC_SD\t\t\t(0x0 << 11)\n+#define DMA_MASTER\t\t\t(0x1 << 20)\n #define BLEN_512BYTESLEN\t\t(0x200 << 0)\n #define NBLK_STPCNT\t\t\t(0x0 << 16)\n #define DE_DISABLE\t\t\t(0x0 << 0)\n@@ -119,6 +127,7 @@ struct omap_hsmmc_plat {\n #define SDBP_PWRON\t\t\t(0x1 << 8)\n #define SDVS_1V8\t\t\t(0x5 << 9)\n #define SDVS_3V0\t\t\t(0x6 << 9)\n+#define DMA_SELECT\t\t\t(0x2 << 3)\n #define ICE_MASK\t\t\t(0x1 << 0)\n #define ICE_STOP\t\t\t(0x0 << 0)\n #define ICS_MASK\t\t\t(0x1 << 1)\n@@ -148,6 +157,7 @@ struct omap_hsmmc_plat {\n #define IE_DTO\t\t\t\t(0x01 << 20)\n #define IE_DCRC\t\t\t\t(0x01 << 21)\n #define IE_DEB\t\t\t\t(0x01 << 22)\n+#define IE_ADMAE\t\t\t(0x01 << 25)\n #define IE_CERR\t\t\t\t(0x01 << 28)\n #define IE_BADA\t\t\t\t(0x01 << 29)\n \ndiff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c\nindex 9f38687..3cac6ea 100644\n--- a/drivers/mmc/omap_hsmmc.c\n+++ b/drivers/mmc/omap_hsmmc.c\n@@ -25,6 +25,7 @@\n #include <config.h>\n #include <common.h>\n #include <malloc.h>\n+#include <memalign.h>\n #include <mmc.h>\n #include <part.h>\n #include <i2c.h>\n@@ -71,11 +72,45 @@ struct omap_hsmmc_data {\n \tint wp_gpio;\n #endif\n #endif\n+\tu8 controller_flags;\n+#ifndef CONFIG_OMAP34XX\n+\tstruct omap_hsmmc_adma_desc *adma_desc_table;\n+\tuint desc_slot;\n+#endif\n+};\n+\n+#ifndef CONFIG_OMAP34XX\n+struct omap_hsmmc_adma_desc {\n+\tu8 attr;\n+\tu8 reserved;\n+\tu16 len;\n+\tu32 addr;\n };\n \n+#define ADMA_MAX_LEN\t63488\n+\n+/* Decriptor table defines */\n+#define ADMA_DESC_ATTR_VALID\t\tBIT(0)\n+#define ADMA_DESC_ATTR_END\t\tBIT(1)\n+#define ADMA_DESC_ATTR_INT\t\tBIT(2)\n+#define ADMA_DESC_ATTR_ACT1\t\tBIT(4)\n+#define ADMA_DESC_ATTR_ACT2\t\tBIT(5)\n+\n+#define ADMA_DESC_TRANSFER_DATA\t\tADMA_DESC_ATTR_ACT2\n+#define ADMA_DESC_LINK_DESC\t(ADMA_DESC_ATTR_ACT1 | ADMA_DESC_ATTR_ACT2)\n+#endif\n+\n /* If we fail after 1 second wait, something is really bad */\n #define MAX_RETRY_MS\t1000\n \n+/* DMA transfers can take a long time if a lot a data is transfered.\n+ * The timeout must take in account the amount of data. Let's assume\n+ * that the time will never exceed 333 ms per MB (in other word we assume\n+ * that the bandwidth is always above 3MB/s).\n+ */\n+#define DMA_TIMEOUT_PER_MB\t333\n+#define OMAP_HSMMC_USE_ADMA\t\t\tBIT(2)\n+\n static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);\n static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,\n \t\t\tunsigned int siz);\n@@ -242,6 +277,11 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)\n \t\t\treturn -ETIMEDOUT;\n \t\t}\n \t}\n+#ifndef CONFIG_OMAP34XX\n+\treg_val = readl(&mmc_base->hl_hwinfo);\n+\tif (reg_val & MADMA_EN)\n+\t\tpriv->controller_flags |= OMAP_HSMMC_USE_ADMA;\n+#endif\n \twritel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);\n \twritel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,\n \t\t&mmc_base->capa);\n@@ -269,8 +309,8 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)\n \twritel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);\n \n \twritel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |\n-\t\tIE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC,\n-\t\t&mmc_base->ie);\n+\t\tIE_CEB | IE_CCRC | IE_ADMAE | IE_CTO | IE_BRR | IE_BWR | IE_TC |\n+\t\tIE_CC, &mmc_base->ie);\n \n \tmmc_init_stream(mmc_base);\n \n@@ -322,6 +362,118 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)\n \t\t}\n \t}\n }\n+\n+#ifndef CONFIG_OMAP34XX\n+static void omap_hsmmc_adma_desc(struct mmc *mmc, char *buf, u16 len, bool end)\n+{\n+\tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n+\tstruct omap_hsmmc_adma_desc *desc;\n+\tu8 attr;\n+\n+\tdesc = &priv->adma_desc_table[priv->desc_slot];\n+\n+\tattr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;\n+\tif (!end)\n+\t\tpriv->desc_slot++;\n+\telse\n+\t\tattr |= ADMA_DESC_ATTR_END;\n+\n+\tdesc->len = len;\n+\tdesc->addr = (u32)buf;\n+\tdesc->reserved = 0;\n+\tdesc->attr = attr;\n+}\n+\n+static void omap_hsmmc_prepare_adma_table(struct mmc *mmc,\n+\t\t\t\t\t  struct mmc_data *data)\n+{\n+\tuint total_len = data->blocksize * data->blocks;\n+\tuint desc_count = DIV_ROUND_UP(total_len, ADMA_MAX_LEN);\n+\tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n+\tint i = desc_count;\n+\tchar *buf;\n+\n+\tpriv->desc_slot = 0;\n+\tpriv->adma_desc_table = (struct omap_hsmmc_adma_desc *)\n+\t\t\t\tmemalign(ARCH_DMA_MINALIGN, desc_count *\n+\t\t\t\tsizeof(struct omap_hsmmc_adma_desc));\n+\n+\tif (data->flags & MMC_DATA_READ)\n+\t\tbuf = data->dest;\n+\telse\n+\t\tbuf = (char *)data->src;\n+\n+\twhile (--i) {\n+\t\tomap_hsmmc_adma_desc(mmc, buf, ADMA_MAX_LEN, false);\n+\t\tbuf += ADMA_MAX_LEN;\n+\t\ttotal_len -= ADMA_MAX_LEN;\n+\t}\n+\n+\tomap_hsmmc_adma_desc(mmc, buf, total_len, true);\n+\n+\tflush_dcache_range((long)priv->adma_desc_table,\n+\t\t\t   (long)priv->adma_desc_table +\n+\t\t\t   ROUND(desc_count *\n+\t\t\t   sizeof(struct omap_hsmmc_adma_desc),\n+\t\t\t   ARCH_DMA_MINALIGN));\n+}\n+\n+static void omap_hsmmc_prepare_data(struct mmc *mmc, struct mmc_data *data)\n+{\n+\tstruct hsmmc *mmc_base;\n+\tstruct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);\n+\tu32 val;\n+\tchar *buf;\n+\n+\tmmc_base = priv->base_addr;\n+\tomap_hsmmc_prepare_adma_table(mmc, data);\n+\n+\tif (data->flags & MMC_DATA_READ)\n+\t\tbuf = data->dest;\n+\telse\n+\t\tbuf = (char *)data->src;\n+\n+\tval = readl(&mmc_base->hctl);\n+\tval |= DMA_SELECT;\n+\twritel(val, &mmc_base->hctl);\n+\n+\tval = readl(&mmc_base->con);\n+\tval |= DMA_MASTER;\n+\twritel(val, &mmc_base->con);\n+\n+\twritel((u32)priv->adma_desc_table, &mmc_base->admasal);\n+\n+\tflush_dcache_range((u32)buf,\n+\t\t\t   (u32)buf +\n+\t\t\t   ROUND(data->blocksize * data->blocks,\n+\t\t\t\t ARCH_DMA_MINALIGN));\n+}\n+\n+static void omap_hsmmc_dma_cleanup(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+\n+\tval = readl(&mmc_base->con);\n+\tval &= ~DMA_MASTER;\n+\twritel(val, &mmc_base->con);\n+\n+\tval = readl(&mmc_base->hctl);\n+\tval &= ~DMA_SELECT;\n+\twritel(val, &mmc_base->hctl);\n+\n+\tkfree(priv->adma_desc_table);\n+}\n+#else\n+#define omap_hsmmc_adma_desc\n+#define omap_hsmmc_prepare_adma_table\n+#define omap_hsmmc_prepare_data\n+#define omap_hsmmc_dma_cleanup\n+#endif\n+\n #if !CONFIG_IS_ENABLED(DM_MMC)\n static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,\n \t\t\tstruct mmc_data *data)\n@@ -332,6 +484,8 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,\n \t\t\tstruct mmc_data *data)\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 #endif\n \tstruct hsmmc *mmc_base;\n \tunsigned int flags, mmc_stat;\n@@ -405,6 +559,14 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,\n \t\t\tflags |= (DP_DATA | DDIR_READ);\n \t\telse\n \t\t\tflags |= (DP_DATA | DDIR_WRITE);\n+\n+#ifndef CONFIG_OMAP34XX\n+\t\tif ((priv->controller_flags & OMAP_HSMMC_USE_ADMA) &&\n+\t\t    !mmc_is_tuning_cmd(cmd->cmdidx)) {\n+\t\t\tomap_hsmmc_prepare_data(mmc, data);\n+\t\t\tflags |= DE_ENABLE;\n+\t\t}\n+#endif\n \t}\n \n \twritel(cmd->cmdarg, &mmc_base->arg);\n@@ -414,7 +576,7 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,\n \tstart = get_timer(0);\n \tdo {\n \t\tmmc_stat = readl(&mmc_base->stat);\n-\t\tif (get_timer(0) - start > MAX_RETRY_MS) {\n+\t\tif (get_timer(start) > MAX_RETRY_MS) {\n \t\t\tprintf(\"%s : timeout: No status update\\n\", __func__);\n \t\t\treturn -ETIMEDOUT;\n \t\t}\n@@ -441,6 +603,41 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,\n \t\t}\n \t}\n \n+#ifndef CONFIG_OMAP34XX\n+\tif ((priv->controller_flags & OMAP_HSMMC_USE_ADMA) && data &&\n+\t    !mmc_is_tuning_cmd(cmd->cmdidx)) {\n+\t\tu32 sz_mb, timeout;\n+\n+\t\tif (mmc_stat & IE_ADMAE) {\n+\t\t\tomap_hsmmc_dma_cleanup(mmc);\n+\t\t\treturn -EIO;\n+\t\t}\n+\n+\t\tsz_mb = DIV_ROUND_UP(data->blocksize *  data->blocks, 1 << 20);\n+\t\ttimeout = sz_mb * DMA_TIMEOUT_PER_MB;\n+\t\tif (timeout < MAX_RETRY_MS)\n+\t\t\ttimeout = MAX_RETRY_MS;\n+\n+\t\tstart = get_timer(0);\n+\t\tdo {\n+\t\t\tmmc_stat = readl(&mmc_base->stat);\n+\t\t\tif (mmc_stat & TC_MASK) {\n+\t\t\t\twritel(readl(&mmc_base->stat) | TC_MASK,\n+\t\t\t\t       &mmc_base->stat);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (get_timer(start) > timeout) {\n+\t\t\t\tprintf(\"%s : DMA timeout: No status update\\n\",\n+\t\t\t\t       __func__);\n+\t\t\t\treturn -ETIMEDOUT;\n+\t\t\t}\n+\t\t} while (1);\n+\n+\t\tomap_hsmmc_dma_cleanup(mmc);\n+\t\treturn 0;\n+\t}\n+#endif\n+\n \tif (data && (data->flags & MMC_DATA_READ)) {\n \t\tmmc_read_data(mmc_base,\tdata->dest,\n \t\t\t\tdata->blocksize * data->blocks);\n","prefixes":["U-Boot","v2","3/5"]}