From patchwork Wed Sep 23 10:42:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Walle X-Patchwork-Id: 1369824 X-Patchwork-Delegate: van.freenix@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=walle.cc Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=walle.cc header.i=@walle.cc header.a=rsa-sha256 header.s=mail2016061301 header.b=EklcoMgv; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BxFD45vwYz9sR4 for ; Wed, 23 Sep 2020 20:44:20 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C5CC38260C; Wed, 23 Sep 2020 12:43:23 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=walle.cc Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; secure) header.d=walle.cc header.i=@walle.cc header.b="EklcoMgv"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 553BA82460; Wed, 23 Sep 2020 12:43:10 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from ssl.serverraum.org (ssl.serverraum.org [IPv6:2a01:4f8:151:8464::1:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0A98682440 for ; Wed, 23 Sep 2020 12:43:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=walle.cc Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=michael@walle.cc Received: from mwalle01.sab.local. (unknown [213.135.10.150]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ssl.serverraum.org (Postfix) with ESMTPSA id 029AD23E4E; Wed, 23 Sep 2020 12:43:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=walle.cc; s=mail2016061301; t=1600857783; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SXXv3AN0jZ/jDchgi0g+JSJAf5y8MnpAb9bzhHnvrjA=; b=EklcoMgvu2zQXjIfBLrXnxydtf1Hf7G02O7+YLYmOf21nXsyBtU4K72rcGXqNThVVcpQAu HGLie2bzCbeo0hcJNEEdAgbB0KRkoNwg5akhL71PtTPlq8eu24AjPicrS4CzKFxp8SLppy Wl02d8Oe8Cyw52jZzgA2b7YnNoyrBRc= From: Michael Walle To: u-boot@lists.denx.de Cc: Michal Simek , Peng Fan , Yangbo Lu , Michael Walle Subject: [PATCH 6/6] mmc: fsl_esdhc: add ADMA2 support Date: Wed, 23 Sep 2020 12:42:52 +0200 Message-Id: <20200923104252.14919-7-michael@walle.cc> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200923104252.14919-1-michael@walle.cc> References: <20200923104252.14919-1-michael@walle.cc> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean Newer eSDHC controllers support ADMA2 descriptor tables which support 64bit DMA addresses. One notable user of addresses in the upper memory segment is the EFI loader. If support is enabled, but the controller doesn't support ADMA2, we will fall back to SDMA (and thus 32 bit DMA addresses only). Signed-off-by: Michael Walle --- drivers/mmc/Kconfig | 8 +++++++ drivers/mmc/fsl_esdhc.c | 50 ++++++++++++++++++++++++++++++++++++----- include/fsl_esdhc.h | 14 ++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 88582db58c..14d7913986 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -755,6 +755,14 @@ config FSL_ESDHC This selects support for the eSDHC (Enhanced Secure Digital Host Controller) found on numerous Freescale/NXP SoCs. +config FSL_ESDHC_SUPPORT_ADMA2 + bool "enable ADMA2 support" + depends on FSL_ESDHC + select MMC_SDHCI_ADMA_HELPERS + help + This enables support for the ADMA2 transfer mode. If supported by the + eSDHC it will allow 64bit DMA addresses. + config FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND bool "enable eSDHC workaround for 3.3v IO reliability issue" depends on FSL_ESDHC && DM_MMC diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index c4acfe10dc..5b6cedd7d7 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -52,8 +53,9 @@ struct fsl_esdhc { char reserved1[8]; /* reserved */ uint fevt; /* Force event register */ uint admaes; /* ADMA error status register */ - uint adsaddr; /* ADMA system address register */ - char reserved2[160]; + uint adsaddrl; /* ADMA system address low register */ + uint adsaddrh; /* ADMA system address high register */ + char reserved2[156]; uint hostver; /* Host controller version register */ char reserved3[4]; /* reserved */ uint dmaerraddr; /* DMA error address register */ @@ -92,6 +94,7 @@ struct fsl_esdhc_priv { struct mmc *mmc; #endif struct udevice *dev; + struct sdhci_adma_desc *adma_desc_table; dma_addr_t dma_addr; }; @@ -219,6 +222,7 @@ static void esdhc_setup_dma(struct fsl_esdhc_priv *priv, struct mmc_data *data) { uint trans_bytes = data->blocksize * data->blocks; struct fsl_esdhc *regs = priv->esdhc_regs; + phys_addr_t adma_addr; void *buf; if (data->flags & MMC_DATA_WRITE) @@ -228,9 +232,29 @@ static void esdhc_setup_dma(struct fsl_esdhc_priv *priv, struct mmc_data *data) priv->dma_addr = dma_map_single(buf, trans_bytes, mmc_get_dma_dir(data)); - if (upper_32_bits(priv->dma_addr)) - printf("Cannot use 64 bit addresses with SDMA\n"); - esdhc_write32(®s->dsaddr, lower_32_bits(priv->dma_addr)); + + if (IS_ENABLED(CONFIG_FSL_ESDHC_SUPPORT_ADMA2) && + priv->adma_desc_table) { + debug("Using ADMA2\n"); + /* prefer ADMA2 if it is available */ + sdhci_prepare_adma_table(priv->adma_desc_table, data, + priv->dma_addr); + + adma_addr = virt_to_phys(priv->adma_desc_table); + esdhc_write32(®s->adsaddrl, lower_32_bits(adma_addr)); + if (IS_ENABLED(CONFIG_DMA_ADDR_T_64BIT)) + esdhc_write32(®s->adsaddrh, upper_32_bits(adma_addr)); + esdhc_clrsetbits32(®s->proctl, PROCTL_DMAS_MASK, + PROCTL_DMAS_ADMA2); + } else { + debug("Using SDMA\n"); + if (upper_32_bits(priv->dma_addr)) + printf("Cannot use 64 bit addresses with SDMA\n"); + esdhc_write32(®s->dsaddr, lower_32_bits(priv->dma_addr)); + esdhc_clrsetbits32(®s->proctl, PROCTL_DMAS_MASK, + PROCTL_DMAS_SDMA); + } + esdhc_write32(®s->blkattr, data->blocks << 16 | data->blocksize); } @@ -801,6 +825,7 @@ static int fsl_esdhc_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct fsl_esdhc_plat *plat = dev_get_platdata(dev); struct fsl_esdhc_priv *priv = dev_get_priv(dev); + u32 caps, hostver; fdt_addr_t addr; struct mmc *mmc; int ret; @@ -815,6 +840,21 @@ static int fsl_esdhc_probe(struct udevice *dev) #endif priv->dev = dev; + if (IS_ENABLED(CONFIG_FSL_ESDHC_SUPPORT_ADMA2)) { + /* + * Only newer eSDHC controllers can do ADMA2 if the ADMA flag + * is set in the host capabilities register. + */ + caps = esdhc_read32(&priv->esdhc_regs->hostcapblt); + hostver = esdhc_read32(&priv->esdhc_regs->hostver); + if (caps & HOSTCAPBLT_DMAS && + HOSTVER_VENDOR(hostver) > VENDOR_V_22) { + priv->adma_desc_table = sdhci_adma_init(); + if (!priv->adma_desc_table) + debug("Could not allocate ADMA tables, falling back to SDMA\n"); + } + } + if (gd->arch.sdhc_per_clk) { priv->sdhc_clk = gd->arch.sdhc_per_clk; priv->is_sdhc_per_clk = true; diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index 7f8f8edc62..b903d15cb9 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -95,6 +95,10 @@ #define PROCTL_DTW_4 0x00000002 #define PROCTL_DTW_8 0x00000004 #define PROCTL_D3CD 0x00000008 +#define PROCTL_DMAS_MASK 0x00000300 +#define PROCTL_DMAS_SDMA 0x00000000 +#define PROCTL_DMAS_ADMA1 0x00000100 +#define PROCTL_DMAS_ADMA2 0x00000300 #define PROCTL_VOLT_SEL 0x00000400 #define CMDARG 0x0002e008 @@ -162,6 +166,16 @@ #define HOSTCAPBLT_DMAS 0x00400000 #define HOSTCAPBLT_HSS 0x00200000 +#define HOSTVER_VENDOR(x) (((x) >> 8) & 0xff) +#define VENDOR_V_10 0x00 +#define VENDOR_V_20 0x10 +#define VENDOR_V_21 0x11 +#define VENDOR_V_22 0x12 +#define VENDOR_V_23 0x13 +#define VENDOR_V_30 0x20 +#define VENDOR_V_31 0x21 +#define VENDOR_V_32 0x22 + struct fsl_esdhc_cfg { phys_addr_t esdhc_base; u32 sdhc_clk;