From patchwork Fri May 12 14:14:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joy Chakraborty X-Patchwork-Id: 681340 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8062FC77B75 for ; Fri, 12 May 2023 14:15:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241484AbjELOPN (ORCPT ); Fri, 12 May 2023 10:15:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241162AbjELOPI (ORCPT ); Fri, 12 May 2023 10:15:08 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 59FBD12E92 for ; Fri, 12 May 2023 07:15:07 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-ba2526a8918so13120761276.1 for ; Fri, 12 May 2023 07:15:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683900906; x=1686492906; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=9fd/5tDM33mlBKRPz7g7eHWJD79X5yTFlYNSGMw+woI=; b=ZtsTNy2PVfhlpb/JuCfk1p8ZXlnYWWxWxMEu1Lva2/0XLeNRSoREIJqChnS3XuVtdr BE5huxYM2URNE4X1IxhxOTZISn4KuZI2Yqn/u6yGjFFj+RInj169E8ItPuxQQGs9QzoV 4Dvr7N/r//TmFUqT233y4l29SSmOpi3WqZsSVqkrH4NscGes5SFDHTVJ8TrYzYpED4Kf 7d23qfy07kmel36g5Qh/hO+vjVplrl5L+5RmkW/RECjDn8VO6EMQ3QulL97z7jfNOtKq e5+3GV/laP5C/Cao4Jsxp0p52Tp/DJuee8K0eFFT0VPDhl/QxO6pMNVlT4e39qP0nYlw 329w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683900906; x=1686492906; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9fd/5tDM33mlBKRPz7g7eHWJD79X5yTFlYNSGMw+woI=; b=fXyXKAlHP4GmP+LF6gBS8snwXElrFv92G18ao2WfEMELAIl9EOD8VtIkJGn0opcAmd c4l7x5XveFadF0ugfTj1dIWEhsRxruFiEVwO6OVjIaKnGuFy2KaLs4tf1zRD3lVwiDzx spCgzmv/QRwHynt8kHZGE8yEtcSze1TG3rg7yLLmnyUvj4fsFWMqKShse/q7NUyj007i hnK87Pjl/QAo8BdEHe2EZ4zRphcHzz9A5eTT6BCFC3pC7zDpyWBt6aEeNVfBgE9/bcoD Mg0b5Z6RhgnqJVvdQWVYbtAEGKtNe2GQutRgodYRPESoya9E9l+2sYDUVG0KDUJD9GqU rYpw== X-Gm-Message-State: AC+VfDx0KkPWuPiIPCJn6SbR4rcOdQmBD/8ey0P8Gw+Khc9+AV7zlftn kKDNDDKpNSckMXR2cKwG/RsrqajQ/9SImw== X-Google-Smtp-Source: ACHHUZ606I3ZcTGrIAGj3KmtJiebDv5RhcP3DxRfkMrJL64OO+mRwOKUmnmEexp2/X66k3JxQdAsUEMcSict+w== X-Received: from joychakr.c.googlers.com ([fda3:e722:ac3:cc00:4f:4b78:c0a8:6ea]) (user=joychakr job=sendgmr) by 2002:a05:6902:114e:b0:b4a:3896:bc17 with SMTP id p14-20020a056902114e00b00b4a3896bc17mr11151964ybu.0.1683900906639; Fri, 12 May 2023 07:15:06 -0700 (PDT) Date: Fri, 12 May 2023 14:14:40 +0000 In-Reply-To: <20230512141445.2026660-1-joychakr@google.com> Mime-Version: 1.0 References: <20230512141445.2026660-1-joychakr@google.com> X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230512141445.2026660-2-joychakr@google.com> Subject: [PATCH v2 1/6] dmaengine: pl330: Separate SRC and DST burst size and len From: Joy Chakraborty To: Vinod Koul Cc: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, manugautam@google.com, danielmentz@google.com, sjadavani@google.com, Joy Chakraborty Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add new variables in request configuration to handle source and destination AxSize and AxLen separately and allow them to have different values. This allows further patches to configure different AxSize and AxLen for optimum bus utilisation. Signed-off-by: Joy Chakraborty --- drivers/dma/pl330.c | 71 +++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0d9257fbdfb0..c006e481b4c5 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -240,6 +240,12 @@ enum pl330_byteswap { #define BYTE_TO_BURST(b, ccr) ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr)) #define BURST_TO_BYTE(c, ccr) ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr)) +#define SRC_BRST_SIZE(ccr) BRST_SIZE(ccr) +#define DST_BRST_SIZE(ccr) (1 << (((ccr) >> CC_DSTBRSTSIZE_SHFT) & 0x7)) + +#define SRC_BRST_LEN(ccr) BRST_LEN(ccr) +#define DST_BRST_LEN(ccr) ((((ccr) >> CC_DSTBRSTLEN_SHFT) & 0xf) + 1) + /* * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req * at 1byte/burst for P<->M and M<->M respectively. @@ -305,8 +311,10 @@ struct pl330_reqcfg { bool nonsecure; bool privileged; bool insnaccess; - unsigned brst_len:5; - unsigned brst_size:3; /* in power of 2 */ + unsigned src_brst_size : 3; /* in power of 2 */ + unsigned src_brst_len:5; + unsigned dst_brst_size : 3; /* in power of 2 */ + unsigned dst_brst_len:5; enum pl330_cachectrl dcctl; enum pl330_cachectrl scctl; @@ -1204,7 +1212,10 @@ static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], const struct _xfer_spec *pxs, int cyc) { int off = 0; - enum pl330_cond cond = BRST_LEN(pxs->ccr) > 1 ? BURST : SINGLE; + enum pl330_cond cond = SINGLE; + + if (SRC_BRST_LEN(pxs->ccr) > 1 || DST_BRST_LEN(pxs->ccr) > 1) + cond = BURST; if (pl330->quirks & PL330_QUIRK_PERIPH_BURST) cond = BURST; @@ -1235,12 +1246,12 @@ static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], * for mem-to-mem, mem-to-dev or dev-to-mem. */ static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], - const struct _xfer_spec *pxs, int transfer_length) + const struct _xfer_spec *pxs, int src_length, int dst_length) { int off = 0; int dregs_ccr; - if (transfer_length == 0) + if (src_length == 0 || dst_length == 0) return off; /* @@ -1253,9 +1264,9 @@ static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], dregs_ccr = pxs->ccr; dregs_ccr &= ~((0xf << CC_SRCBRSTLEN_SHFT) | (0xf << CC_DSTBRSTLEN_SHFT)); - dregs_ccr |= (((transfer_length - 1) & 0xf) << + dregs_ccr |= (((src_length - 1) & 0xf) << CC_SRCBRSTLEN_SHFT); - dregs_ccr |= (((transfer_length - 1) & 0xf) << + dregs_ccr |= (((dst_length - 1) & 0xf) << CC_DSTBRSTLEN_SHFT); switch (pxs->desc->rqtype) { @@ -1369,16 +1380,18 @@ static inline int _setup_loops(struct pl330_dmac *pl330, struct pl330_xfer *x = &pxs->desc->px; u32 ccr = pxs->ccr; unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr); - int num_dregs = (x->bytes - BURST_TO_BYTE(bursts, ccr)) / - BRST_SIZE(ccr); - int off = 0; + int num_dreg_bytes = x->bytes - BURST_TO_BYTE(bursts, ccr); + int num_src_dregs, num_dst_dregs, off = 0; + + num_src_dregs = num_dreg_bytes / SRC_BRST_SIZE(ccr); + num_dst_dregs = num_dreg_bytes / DST_BRST_SIZE(ccr); while (bursts) { c = bursts; off += _loop(pl330, dry_run, &buf[off], &c, pxs); bursts -= c; } - off += _dregs(pl330, dry_run, &buf[off], pxs, num_dregs); + off += _dregs(pl330, dry_run, &buf[off], pxs, num_src_dregs, num_dst_dregs); return off; } @@ -1446,11 +1459,11 @@ static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc) if (rqc->insnaccess) ccr |= CC_SRCIA | CC_DSTIA; - ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT); - ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT); + ccr |= (((rqc->src_brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT); + ccr |= (((rqc->dst_brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT); - ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT); - ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT); + ccr |= (rqc->src_brst_size << CC_SRCBRSTSIZE_SHFT); + ccr |= (rqc->dst_brst_size << CC_DSTBRSTSIZE_SHFT); ccr |= (rqc->scctl << CC_SRCCCTRL_SHFT); ccr |= (rqc->dcctl << CC_DSTCCTRL_SHFT); @@ -2656,7 +2669,7 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len) burst_len = pl330->pcfg.data_bus_width / 8; burst_len *= pl330->pcfg.data_buf_dep / pl330->pcfg.num_chan; - burst_len >>= desc->rqcfg.brst_size; + burst_len >>= desc->rqcfg.src_brst_size; /* src/dst_burst_len can't be more than 16 */ if (burst_len > PL330_MAX_BURST) @@ -2735,8 +2748,10 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( } desc->rqtype = direction; - desc->rqcfg.brst_size = pch->burst_sz; - desc->rqcfg.brst_len = pch->burst_len; + desc->rqcfg.src_brst_size = pch->burst_sz; + desc->rqcfg.src_brst_len = pch->burst_len; + desc->rqcfg.dst_brst_size = pch->burst_sz; + desc->rqcfg.dst_brst_len = pch->burst_len; desc->bytes_requested = period_len; fill_px(&desc->px, dst, src, period_len); @@ -2789,17 +2804,21 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, while ((src | dst | len) & (burst - 1)) burst /= 2; - desc->rqcfg.brst_size = 0; - while (burst != (1 << desc->rqcfg.brst_size)) - desc->rqcfg.brst_size++; + desc->rqcfg.src_brst_size = 0; + while (burst != (1 << desc->rqcfg.src_brst_size)) + desc->rqcfg.src_brst_size++; - desc->rqcfg.brst_len = get_burst_len(desc, len); + desc->rqcfg.src_brst_len = get_burst_len(desc, len); /* * If burst size is smaller than bus width then make sure we only * transfer one at a time to avoid a burst stradling an MFIFO entry. */ if (burst * 8 < pl330->pcfg.data_bus_width) - desc->rqcfg.brst_len = 1; + desc->rqcfg.src_brst_len = 1; + + /* For Mem2Mem, set destination AxSize and AxLen same as source*/ + desc->rqcfg.dst_brst_len = desc->rqcfg.src_brst_len; + desc->rqcfg.dst_brst_size = desc->rqcfg.src_brst_size; desc->bytes_requested = len; @@ -2879,8 +2898,10 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, sg_dma_len(sg)); } - desc->rqcfg.brst_size = pch->burst_sz; - desc->rqcfg.brst_len = pch->burst_len; + desc->rqcfg.src_brst_size = pch->burst_sz; + desc->rqcfg.src_brst_len = pch->burst_len; + desc->rqcfg.dst_brst_size = pch->burst_sz; + desc->rqcfg.dst_brst_len = pch->burst_len; desc->rqtype = direction; desc->bytes_requested = sg_dma_len(sg); } From patchwork Fri May 12 14:14:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joy Chakraborty X-Patchwork-Id: 681339 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 284AEC77B75 for ; Fri, 12 May 2023 14:15:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241528AbjELOPd (ORCPT ); Fri, 12 May 2023 10:15:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47296 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241490AbjELOPY (ORCPT ); Fri, 12 May 2023 10:15:24 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC28914922 for ; Fri, 12 May 2023 07:15:16 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-55a40d32a6bso110425187b3.2 for ; Fri, 12 May 2023 07:15:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683900916; x=1686492916; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=AwCGXSf8iY+/DH2QgsH2WgzsBbqjZwTLYrp1XXczDUM=; b=OY9dkKT5GQA0dusKiKaS7jrpoAGc7STMoAC5iq8ZfQ23vIfNvff8zDGgoY30mJ/5tD 9i5nx/eeF4spSmwJa6idZkSXZNinZO9XvLfzF6UvdZkIqXG9NT4b8J8zNPdj8LzTmHxk 7REBcii9VONQpxmUV1ZgJuykuVbQPVtAhPWlMybn7UfMyv8CfnQ7ky/YyFRHSkAev3PK MeZXSlsVN9NAYV0dajL373J8mY+unWtwU0Y3WI1cw/zYGoJPInHFFssN72jUC6uC7mFG TIRG8oqiyD1k+RdxYwV8T1XyV86Lt927tbp7/DrwyLP1upxf9Pd2O0L0eEZ2NhxUSfZf BmbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683900916; x=1686492916; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=AwCGXSf8iY+/DH2QgsH2WgzsBbqjZwTLYrp1XXczDUM=; b=eEcJ6iDozfqMPwA6ZuJNjCzoseVFjVe8erbKhnoyLMWYIrXU7E4HZDR1V8C5JsmyNL iBc5spWgkMUrvPPFj2AgdFFGcxU8kOkEafLfppBxaW5at6un0xdGw6VGGNqC+ZJTYlCh YKCNI19SMfuHAE8vJuLYPiyFt955E2viaoR++6MSJG6/HaBWxYZqIZrga23dM8zZFib/ kQxQC2S/hf155R+HDngCAnbjpCiuzhjn8Nv63+PaJmvKby9ih+9FPHFVtojnIhhYmUdz I0AYUmTsRA2f49UnvmL5Au6ikBNUkbn63UhwV018BZv+YEzgR7B6s2uiq5JRP43HqHaS IIeg== X-Gm-Message-State: AC+VfDyyZFRti1qiVhXAiKJMbHUHAPHPV56o5lyctC0lUYg7xz79weep WzvwsGzjDedSx6XYrFQP3pTTuiXsfcQpZg== X-Google-Smtp-Source: ACHHUZ6vj73ZJJY9u+8pIa7SQmcBCLaiwjS1XLKrddb4JGDp5BRcKH1etJcsBSg/adpZUKOfhQdn8y9RDHibrQ== X-Received: from joychakr.c.googlers.com ([fda3:e722:ac3:cc00:4f:4b78:c0a8:6ea]) (user=joychakr job=sendgmr) by 2002:a81:a9c3:0:b0:54c:a67:90b with SMTP id g186-20020a81a9c3000000b0054c0a67090bmr16185230ywh.5.1683900915935; Fri, 12 May 2023 07:15:15 -0700 (PDT) Date: Fri, 12 May 2023 14:14:42 +0000 In-Reply-To: <20230512141445.2026660-1-joychakr@google.com> Mime-Version: 1.0 References: <20230512141445.2026660-1-joychakr@google.com> X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230512141445.2026660-4-joychakr@google.com> Subject: [PATCH v2 3/6] dmaengine: pl330: Change if-else to switch-case for consistency From: Joy Chakraborty To: Vinod Koul Cc: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, manugautam@google.com, danielmentz@google.com, sjadavani@google.com, Joy Chakraborty Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Change if-else to switch-case in pl330_prep_slave_sg() function for consistency with other peripheral transfer functions in the driver. Signed-off-by: Joy Chakraborty --- drivers/dma/pl330.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 39a66ff29e27..746da0bbea92 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2883,16 +2883,21 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, else list_add_tail(&desc->node, &first->node); - if (direction == DMA_MEM_TO_DEV) { + switch (direction) { + case DMA_MEM_TO_DEV: desc->rqcfg.src_inc = 1; desc->rqcfg.dst_inc = 0; fill_px(&desc->px, pch->fifo_dma, sg_dma_address(sg), sg_dma_len(sg)); - } else { + break; + case DMA_DEV_TO_MEM: desc->rqcfg.src_inc = 0; desc->rqcfg.dst_inc = 1; fill_px(&desc->px, sg_dma_address(sg), pch->fifo_dma, sg_dma_len(sg)); + break; + default: + break; } desc->rqcfg.src_brst_size = pch->burst_sz; From patchwork Fri May 12 14:14:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joy Chakraborty X-Patchwork-Id: 681338 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 97991C77B75 for ; Fri, 12 May 2023 14:15:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241498AbjELOPw (ORCPT ); Fri, 12 May 2023 10:15:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46888 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241512AbjELOPk (ORCPT ); Fri, 12 May 2023 10:15:40 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9AC6514E53 for ; Fri, 12 May 2023 07:15:27 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-56098b41d42so57933337b3.0 for ; Fri, 12 May 2023 07:15:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683900926; x=1686492926; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=DBrF5DHnKIcDo8+7KXBxIWAhYs0e5wcmWXF/2mvOoX0=; b=EONdOzyG1A039q9TIagzHY6fFI1rVU8j8RfaY005zsbMET+fIElC7gxK8sx0Vsbb+s pSTTsT66jPni2V+txz15o1bHYwb+q3i1Ro2WMm9WcWd6Wb15w8vYK+acVehdrA2TGnkQ rMM8mVUCubXv1/aIYEsmdbP3RS71eBBvPTgxZO9ZFY9MbiKaGrI09akfU/7GUPivWGAv ncwdUmZTbtP9/bSGq7Sc8MgGVVEjADk2Xls/KOw8jR6SftsyaPO0RSsn0UMNBpaaaQaR EOoTQ+i5XopPmCMoVmtL7yfxALXdH4BcwshdmcXjv/sWuRx6ztWLCphAchPsjNNjuc5C kdiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683900926; x=1686492926; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=DBrF5DHnKIcDo8+7KXBxIWAhYs0e5wcmWXF/2mvOoX0=; b=hGxlGTVPz0RbIfx3vp5cWUG0dlLguo/5aSWO76kScX8oWKMEBBcsnzop6qnFMnAbW7 9+UsPbKC5VFDQGOnSwTNksJnEqACbVnCgpob6c1EI1XLSz5ODO/yBEMGKdB3n+POTQTH gZNv7gbSJ0qe6f3o8Uhe7AXmxZHW2yd6rgiazU5DRIddukCsA8mLpMy9aNfxUuqRY0Pk fy0v4sqBEilD7PX3E5V7wX8Y+BjQvdu3LcA40XpoBsNpKlIHvfW/KpcU/h/FUMOa4g9I yUqHXJPfb8ce8MxM1ng3cYwBAYmyEhHlIkHUAkqYxz6jYyuoiJif++Lr+RpheSMLxMKG EpHA== X-Gm-Message-State: AC+VfDzlxxGJ7/mGfPK6pIzoJE+AKxGe3262+pdblMVXxzpEpA7ksVw9 5QBkONqVxWt0cbbwMa36T3FERUAo8Z1WpA== X-Google-Smtp-Source: ACHHUZ74NTF891q+rha9vQxX0ztAqHF8xmg+06mHuF47o0U+NFSy8mVkCqG5vTx05WHIlOepTiBReOAqZ/CQNA== X-Received: from joychakr.c.googlers.com ([fda3:e722:ac3:cc00:4f:4b78:c0a8:6ea]) (user=joychakr job=sendgmr) by 2002:a81:bd52:0:b0:54f:b986:9c60 with SMTP id n18-20020a81bd52000000b0054fb9869c60mr16276082ywk.7.1683900926764; Fri, 12 May 2023 07:15:26 -0700 (PDT) Date: Fri, 12 May 2023 14:14:44 +0000 In-Reply-To: <20230512141445.2026660-1-joychakr@google.com> Mime-Version: 1.0 References: <20230512141445.2026660-1-joychakr@google.com> X-Mailer: git-send-email 2.40.1.606.ga4b1b128d6-goog Message-ID: <20230512141445.2026660-6-joychakr@google.com> Subject: [PATCH v2 5/6] dmaengine: pl330: Optimize AxSize for peripheral usecases From: Joy Chakraborty To: Vinod Koul Cc: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, manugautam@google.com, danielmentz@google.com, sjadavani@google.com, Joy Chakraborty Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add logic to choose the maximum possible AxSize for transactions towards memory during usecases which copy data between memory and peripherals. Currently PL330 driver chooses equal AxLen and AxSize for both loads and stores to/from memory and peripherals which is inefficient towards memory as the whole bus width is not used for transfers as a peripheral might be limited to use only a narrow size of the buswidth available. Example scenario: A peripheral might require data byte by byte which would make AxSize = 1 byte and AxLen = 16 for both load from memory and store to Peripheral. This can be optimized for memory by using maximum AxSize (say 16bytes) then load from memory can be done with AxSize = 16byte, AxLen = 1 and store to peripheral with AxSize = 1byte, AxLen = 16 beats. Instruction setup post changes : 512bytes copy from Memory(16bytes * 4beats) to Peripheral(4bytes * 16 beats) --- DMAMOV CCR 0xbd0239 DMAMOV SAR 0xffffe000 DMAMOV DAR 0xffffc860 DMALP_1 7 DMAFLUSHP 0 DMAWFPB 0 DMALDB DMASTPB 0 DMALPENDA_1 bjmpto_7 DMASEV 3 DMAEND --- Signed-off-by: Joy Chakraborty --- drivers/dma/pl330.c | 92 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 14 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index e5e610c91f18..46e254fd4007 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2677,6 +2677,52 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, unsigned int brst_s return burst_len; } +/* + * Returns burst size to be used to copy data from/to memory during a + * peripheral transfer + */ +static unsigned int get_periph_mem_brst_sz(dma_addr_t addr, size_t len, + struct dma_pl330_chan *pch) +{ + unsigned int burst; + + /* Select max possible burst size */ + burst = pch->dmac->pcfg.data_bus_width / 8; + + /* + * Make sure we use a burst size that aligns with the memory and length. + */ + while ((addr | len) & (burst - 1)) + burst /= 2; + + return __ffs(burst); +} + +/* + * Returns burst length to be used to copy data from/to memory during a + * peripheral transfer + */ +static unsigned int get_periph_mem_brst_len(struct dma_pl330_desc *desc, + struct dma_pl330_chan *pch, + unsigned int burst_size) +{ + unsigned int burst_len = pch->burst_len; + + if (burst_size != pch->burst_sz) { + /* Select max possible burst len */ + burst_len = get_burst_len(desc, burst_size); + + /* + * Adjust AxLen to keep number of bytes same in Load/Store + */ + if (burst_size > pch->burst_sz) + burst_len = pch->burst_len >> (burst_size - pch->burst_sz); + else + pch->burst_len = burst_len >> (pch->burst_sz - burst_size); + } + return burst_len; +} + static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( struct dma_chan *chan, dma_addr_t dma_addr, size_t len, size_t period_len, enum dma_transfer_direction direction, @@ -2684,8 +2730,8 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( { struct dma_pl330_desc *desc = NULL, *first = NULL; struct dma_pl330_chan *pch = to_pchan(chan); + unsigned int i, burst_size, burst_len; struct pl330_dmac *pl330 = pch->dmac; - unsigned int i; dma_addr_t dst; dma_addr_t src; @@ -2729,28 +2775,35 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( return NULL; } + burst_size = get_periph_mem_brst_sz(dma_addr, period_len, pch); + burst_len = get_periph_mem_brst_len(desc, pch, burst_size); + switch (direction) { case DMA_MEM_TO_DEV: desc->rqcfg.src_inc = 1; desc->rqcfg.dst_inc = 0; src = dma_addr; dst = pch->fifo_dma; + desc->rqcfg.src_brst_size = burst_size; + desc->rqcfg.src_brst_len = burst_len; + desc->rqcfg.dst_brst_size = pch->burst_sz; + desc->rqcfg.dst_brst_len = pch->burst_len; break; case DMA_DEV_TO_MEM: desc->rqcfg.src_inc = 0; desc->rqcfg.dst_inc = 1; src = pch->fifo_dma; dst = dma_addr; + desc->rqcfg.src_brst_size = pch->burst_sz; + desc->rqcfg.src_brst_len = pch->burst_len; + desc->rqcfg.dst_brst_size = burst_size; + desc->rqcfg.dst_brst_len = burst_len; break; default: break; } desc->rqtype = direction; - desc->rqcfg.src_brst_size = pch->burst_sz; - desc->rqcfg.src_brst_len = pch->burst_len; - desc->rqcfg.dst_brst_size = pch->burst_sz; - desc->rqcfg.dst_brst_len = pch->burst_len; desc->bytes_requested = period_len; fill_px(&desc->px, dst, src, period_len); @@ -2850,7 +2903,10 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, { struct dma_pl330_desc *first, *desc = NULL; struct dma_pl330_chan *pch = to_pchan(chan); + unsigned int burst_size, burst_len; struct scatterlist *sg; + dma_addr_t mem_addr; + size_t len; int i; if (unlikely(!pch || !sgl || !sg_len)) @@ -2882,29 +2938,37 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, else list_add_tail(&desc->node, &first->node); + mem_addr = sg_dma_address(sg); + len = sg_dma_len(sg); + + burst_size = get_periph_mem_brst_sz(mem_addr, len, pch); + burst_len = get_periph_mem_brst_len(desc, pch, burst_size); + switch (direction) { case DMA_MEM_TO_DEV: desc->rqcfg.src_inc = 1; desc->rqcfg.dst_inc = 0; - fill_px(&desc->px, pch->fifo_dma, sg_dma_address(sg), - sg_dma_len(sg)); + desc->rqcfg.src_brst_size = burst_size; + desc->rqcfg.src_brst_len = burst_len; + desc->rqcfg.dst_brst_size = pch->burst_sz; + desc->rqcfg.dst_brst_len = pch->burst_len; + fill_px(&desc->px, pch->fifo_dma, mem_addr, len); break; case DMA_DEV_TO_MEM: desc->rqcfg.src_inc = 0; desc->rqcfg.dst_inc = 1; - fill_px(&desc->px, sg_dma_address(sg), pch->fifo_dma, - sg_dma_len(sg)); + desc->rqcfg.src_brst_size = pch->burst_sz; + desc->rqcfg.src_brst_len = pch->burst_len; + desc->rqcfg.dst_brst_size = burst_size; + desc->rqcfg.dst_brst_len = burst_len; + fill_px(&desc->px, mem_addr, pch->fifo_dma, len); break; default: break; } - desc->rqcfg.src_brst_size = pch->burst_sz; - desc->rqcfg.src_brst_len = pch->burst_len; - desc->rqcfg.dst_brst_size = pch->burst_sz; - desc->rqcfg.dst_brst_len = pch->burst_len; desc->rqtype = direction; - desc->bytes_requested = sg_dma_len(sg); + desc->bytes_requested = len; } /* Return the last desc in the chain */