Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3464090imm; Sun, 29 Jul 2018 19:57:24 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcZz0E3RzXgHR9v2aXX/FOQKOuSDXMKDkUvjo5GwiMfugBIMpJc7+DsA8wcvMQODRTGTJxo X-Received: by 2002:a62:f206:: with SMTP id m6-v6mr15926753pfh.171.1532919444239; Sun, 29 Jul 2018 19:57:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532919444; cv=none; d=google.com; s=arc-20160816; b=Uh8Hg4A3wmTi8l0c6/WtTVGlLarA9XBfFlwO2OKc/LUK9OndVZkb/i3A5sgdx1iQkm xaZMQ6biB09F6VFhlRFYClLNEYikA04dN7S+RDedH6Qa+4itrdTjzNHN2ZOSDsOkI9gD uIKwPE/vk4W6ctWwUUWpQHSOjH86dxv4UzahXuA/8YtygAf7Pjmve4rdVkuA0PMFIQgX F8fxh6vlaU3ag/AhBkn0OsTJb0qXt6jnMJQu4viOSc8zK7npSRcFKHsNzByJyg6QMCg4 /TUcZauL6aHIwG2FxmJPvIg5NXEjUIjR1cHTNBqRk/FhMJpAGmxr59hE0uXcfZ4h1Sb7 vbYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:feedback-id:cc:to:subject:message-id:date :from:references:in-reply-to:mime-version:dkim-signature :dkim-signature:arc-authentication-results; bh=nS4fh6jDaTjGqZXReVVG5DztAUkFflFJIl1GJFIIsSk=; b=Pq2USmOvRwwXfTOXPyoZ47RE9UdQVKt/fWtHHGXPM9Vc0hu9k5DAcc7/YtFtZwMTI2 m40EBmNCt6KOEjS/l7FQ9705CQHfoF2HGOwhNIL0IuIAJhzu34B0zgAW1rbLBg2w0blz JF4KBSvBMD7gDeFqasEYtcCvsmVDMrohZMHZNOb4qqg959B7NYpkEYRAqZTPxAtB7bKw H1kfhgHs5YIByB3TTY7bhG4syLAxoGkbWoGeZz4PYM5AsKhRf+ZQc+zGN8J4PzcnHpTW 7ieuepZK2+H8v9RWjFNeuHE6GpGRiJOhyPxYR6TfQfuNXJzJjTZ1knit2dvJLiJc3cIs jwcw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.com header.s=cjonuzaf4apohm6q2sqksleozwz3sz4m header.b=KdUKFlSK; dkim=pass header.i=@amazonses.com header.s=7v7vs6w47njt4pimodk5mmttbegzsi6n header.b=Jh2boIl+; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j24-v6si9651262pfn.363.2018.07.29.19.57.09; Sun, 29 Jul 2018 19:57:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.com header.s=cjonuzaf4apohm6q2sqksleozwz3sz4m header.b=KdUKFlSK; dkim=pass header.i=@amazonses.com header.s=7v7vs6w47njt4pimodk5mmttbegzsi6n header.b=Jh2boIl+; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726093AbeG3E3L (ORCPT + 99 others); Mon, 30 Jul 2018 00:29:11 -0400 Received: from a27-29.smtp-out.us-west-2.amazonses.com ([54.240.27.29]:47876 "EHLO a27-29.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725811AbeG3E3K (ORCPT ); Mon, 30 Jul 2018 00:29:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=cjonuzaf4apohm6q2sqksleozwz3sz4m; d=linux.com; t=1532919381; h=MIME-Version:In-Reply-To:References:From:Date:Message-ID:Subject:To:Cc:Content-Type; bh=gI6GOBq0GcjUc5KLZYsh2n/9mCl1ia4iuwC8AByk8hw=; b=KdUKFlSKIYqbpr/GRYUvoneuhLL9ELIirE92kAqBO4GpE/4cOR6hm00nzNgZWABg kNRwQP0gr2QJYPfUC+lSHABpfZPBapRPIiQ+xivlPdEVMRV/0pCapHIHmyPkCH1U/Nj Zs/rUlQ7JGjDBQpq4RcAanI0Ugz6VL226Y2eDfs0= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=7v7vs6w47njt4pimodk5mmttbegzsi6n; d=amazonses.com; t=1532919381; h=MIME-Version:In-Reply-To:References:From:Date:Message-ID:Subject:To:Cc:Content-Type:Feedback-ID; bh=gI6GOBq0GcjUc5KLZYsh2n/9mCl1ia4iuwC8AByk8hw=; b=Jh2boIl+Rw3x8Ijr58ZRfOv6RDBnFf5khdu/j9gVt07UQy4SOoegzuZFOvCBEVF3 56zM7VH95IFw7QEHGLFk3qEoka8OablC/7X3oBASFvqyygZ606do5fQ1t7SkM4neOCO EdykV2SZcvbthWWJrH+RCUJMK+zAzbLT/YGHKKrU= X-Gm-Message-State: AOUpUlG0Br+tgDFnqBI0ZKp9+Moq+H8k9Dpx+um7C/rujAln0hWmhYRn Z3C3jt+JR6emRqW32QaVGg9htYPDueNMBmSRvyA= X-Received: by 2002:a81:d52:: with SMTP id 79-v6mr8059419ywn.123.1532919378207; Sun, 29 Jul 2018 19:56:18 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <20180730104636.1a3e6c81@xhacker.debian> References: <20180730104228.28b58bd0@xhacker.debian> <20180730104636.1a3e6c81@xhacker.debian> From: Matthew Leon Date: Mon, 30 Jul 2018 02:56:20 +0000 X-Gmail-Original-Message-ID: Message-ID: <01010164e91d7bda-aa616cbf-7bb2-4fe4-85e5-a18e16433fde-000000@us-west-2.amazonses.com> Subject: Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation To: Jisheng Zhang Cc: Adrian Hunter , Ulf Hansson , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Content-Type: multipart/alternative; boundary="00000000000001ea2605722e9bb0" X-SES-Outgoing: 2018.07.30-54.240.27.29 Feedback-ID: 1.us-west-2.3ULHQnc20aILdVzjlbQ8UqO1WRWzA1U01b2uFAcT62w=:AmazonSES Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --00000000000001ea2605722e9bb0 Content-Type: text/plain; charset="UTF-8" Hey Jisheng, Shouldn't we be splitting until all DMA blocks are less than 128M boundary? I am a noob, but I think we should be prepared for boundaries that when split in two, will still be greater than 128M. Feel free to disagree but please explain why I may be wrong. Thank-you. Sincerely, Matthew Leon On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang wrote: > When using DMA, if the DMA addr spans 128MB boundary, we have to split > the DMA transfer into two so that each one doesn't exceed the boundary. > > Signed-off-by: Jisheng Zhang > --- > drivers/mmc/host/sdhci-of-dwcmshc.c | 43 +++++++++++++++++++++++++++++ > 1 file changed, 43 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c > b/drivers/mmc/host/sdhci-of-dwcmshc.c > index 1b7cd144fb01..e890fc8f5284 100644 > --- a/drivers/mmc/host/sdhci-of-dwcmshc.c > +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c > @@ -8,21 +8,52 @@ > */ > > #include > +#include > #include > #include > +#include > > #include "sdhci-pltfm.h" > > +#define BOUNDARY_OK(addr, len) \ > + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) > + > struct dwcmshc_priv { > struct clk *bus_clk; > }; > > +/* > + * if DMA addr spans 128MB boundary, we split the DMA transfer into two > + * so that the DMA transfer doesn't exceed the boundary. > + */ > +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, > + void *desc, dma_addr_t addr, > + int len, unsigned int cmd) > +{ > + int tmplen, offset; > + > + if (likely(!len || BOUNDARY_OK(addr, len))) > + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); > + > + offset = addr & (SZ_128M - 1); > + tmplen = SZ_128M - offset; > + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); > + > + addr += tmplen; > + len -= tmplen; > + desc += host->desc_sz; > + _sdhci_adma_write_desc(host, desc, addr, len, cmd); > + > + return host->desc_sz * 2; > +} > + > static const struct sdhci_ops sdhci_dwcmshc_ops = { > .set_clock = sdhci_set_clock, > .set_bus_width = sdhci_set_bus_width, > .set_uhs_signaling = sdhci_set_uhs_signaling, > .get_max_clock = sdhci_pltfm_clk_get_max_clock, > .reset = sdhci_reset, > + .adma_write_desc = dwcmshc_adma_write_desc, > }; > > static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { > @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev) > struct sdhci_host *host; > struct dwcmshc_priv *priv; > int err; > + u32 extra; > > host = sdhci_pltfm_init(pdev, &sdhci_dwcmshc_pdata, > sizeof(struct dwcmshc_priv)); > if (IS_ERR(host)) > return PTR_ERR(host); > > + /* > + * The DMA descriptor table number is calculated as the maximum > + * number of segments times 2, to allow for an alignment > + * descriptor for each segment, plus 1 for a nop end descriptor, > + * plus extra number for cross 128M boundary handling. > + */ > + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); > + if (extra > SDHCI_MAX_SEGS) > + extra = SDHCI_MAX_SEGS; > + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1 + extra; > + > pltfm_host = sdhci_priv(host); > priv = sdhci_pltfm_priv(pltfm_host); > > -- > 2.18.0 > > --00000000000001ea2605722e9bb0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hey Jisheng,

Shouldn't w= e be splitting until all DMA blocks are less than 128M boundary? I am a noo= b, but I think we should be prepared for boundaries that when split in two,= will still be greater than 128M. Feel free to disagree but please explain = why I may be wrong. Thank-you.

Sincerely,
Matthew Leon

On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang <Jisheng.Zhang@synaptics.com> wrote:
When using DMA, if the DMA addr spans 128MB boundary, we have= to split
the DMA transfer into two so that each one doesn't exceed the boundary.=

Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
---
=C2=A0drivers/mmc/host/sdhci-of-dwcmshc.c | 43 +++++++++++++++++++++++= ++++++
=C2=A01 file changed, 43 insertions(+)

diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sd= hci-of-dwcmshc.c
index 1b7cd144fb01..e890fc8f5284 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -8,21 +8,52 @@
=C2=A0 */

=C2=A0#include <linux/clk.h>
+#include <linux/mm.h>
=C2=A0#include <linux/module.h>
=C2=A0#include <linux/of.h>
+#include <linux/sizes.h>

=C2=A0#include "sdhci-pltfm.h"

+#define BOUNDARY_OK(addr, len) \
+=C2=A0 =C2=A0 =C2=A0 =C2=A0((addr | (SZ_128M - 1)) =3D=3D ((addr + len - 1= ) | (SZ_128M - 1)))
+
=C2=A0struct dwcmshc_priv {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct clk=C2=A0 =C2=A0 =C2=A0 *bus_clk;
=C2=A0};

+/*
+ * if DMA addr spans 128MB boundary, we split the DMA transfer into two + * so that the DMA transfer doesn't exceed the boundary.
+ */
+static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0void *desc, dma_addr_t addr,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0int len, unsigned int cmd)
+{
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int tmplen, offset;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (likely(!len || BOUNDARY_OK(addr, len)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return _sdhci_adma_= write_desc(host, desc, addr, len, cmd);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0offset =3D addr & (SZ_128M - 1);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0tmplen =3D SZ_128M - offset;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0_sdhci_adma_write_desc(host, desc, addr, tmplen= , cmd);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0addr +=3D tmplen;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0len -=3D tmplen;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0desc +=3D host->desc_sz;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0_sdhci_adma_write_desc(host, desc, addr, len, c= md);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return host->desc_sz * 2;
+}
+
=C2=A0static const struct sdhci_ops sdhci_dwcmshc_ops =3D {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .set_clock=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =3D sdhci_set_clock,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .set_bus_width=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =3D sdhci_set_bus_width,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .set_uhs_signaling=C2=A0 =C2=A0 =C2=A0 =3D sdhc= i_set_uhs_signaling,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .get_max_clock=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =3D sdhci_pltfm_clk_get_max_clock,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 .reset=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =3D sdhci_reset,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0.adma_write_desc=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D= dwcmshc_adma_write_desc,
=C2=A0};

=C2=A0static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata =3D {
@@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev)<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct sdhci_host *host;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct dwcmshc_priv *priv;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 int err;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0u32 extra;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 host =3D sdhci_pltfm_init(pdev, &sdhci_dwcm= shc_pdata,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeof(struct dwcmshc_priv));
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (IS_ERR(host))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return PTR_ERR(host= );

+=C2=A0 =C2=A0 =C2=A0 =C2=A0/*
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * The DMA descriptor table number is calculate= d as the maximum
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * number of segments times 2, to allow for an = alignment
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * descriptor for each segment, plus 1 for a no= p end descriptor,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 * plus extra number for cross 128M boundary ha= ndling.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0extra =3D DIV_ROUND_UP(totalram_pages, SZ_128M = / PAGE_SIZE);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (extra > SDHCI_MAX_SEGS)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0extra =3D SDHCI_MAX= _SEGS;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0host->adma_table_num =3D SDHCI_MAX_SEGS * 2 = + 1 + extra;
+
=C2=A0 =C2=A0 =C2=A0 =C2=A0 pltfm_host =3D sdhci_priv(host);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 priv =3D sdhci_pltfm_priv(pltfm_host);
=C2=A0
--
2.18.0


--00000000000001ea2605722e9bb0--