Received: by 2002:a05:6358:9144:b0:117:f937:c515 with SMTP id r4csp665212rwr; Thu, 4 May 2023 08:07:16 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5eGBWRQ3U7IZ8KDVM5xobB27j00+2Aa9pKIzUNiXBd5ILUs10Edwr2a52//GmUVNzQ5u1r X-Received: by 2002:a17:90a:4d4e:b0:24e:2021:b410 with SMTP id l14-20020a17090a4d4e00b0024e2021b410mr2584071pjh.14.1683212836065; Thu, 04 May 2023 08:07:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683212836; cv=none; d=google.com; s=arc-20160816; b=zxlnUiQCiBbzl5K8x4oWdSd5h+WyxpevYMMpdHpV677e+ehiyUqIsA7LdPAqUJCf0U vzYk6zzT2kRQwAw3zztgk+gCU5NPwT8UwXj48Q9u3nJRvcifMTq8yxzNPZadi+uQe3yL EntnsyR4I2OfuqcRZjgPAWI0W/C48ah6aTLD5UJlqQDw34NdXbHHv6wVI9hoEdD1WN90 Wao9B/DN/ynLosB48RsDRLkwOGCXN5Bo3tzNHjxEWqv0ZGeOzqGyJURKo7PW+uIC+/Hh F3adZIxVNUfa4TCV2ikd+xIWdFHaFtAqm8EXQpE+hf8P5kwz8uH9oLj7pXXTq5B3yjeG OZpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:dkim-signature; bh=FyjCHPBh44PN3ytyHlUnOM1ASgpqY1cxsBMty1tbu/M=; b=JIBiYffYn0uosiHGc3+Y9FJJy6p74VCmmHdyNMFj1uvGOcfAsJwBLudtdCPDu+YK8I uwPsovIed73mOuaPEFeehuB/yB0z3FXRHmHvFpvNTA6GOHfFid5qK44ui8taVBmsSkEG /rL55ShbMnmYILqDT/+hhKNH6C6v4euHOVhCdnc+AOW3vDKX3/bN1TnOaROXTlG9Fmqd ctVBAI+5p3y/fFyYzabmz0Ytvv+1N9uNwKIz1WeoUQOaSkI90L5vLJY3CBiXQI6uNw1E GzY0sZXXEN21KmzYPcWPclZpMh2Pt1q/oeDTO1AJNuhR6DTa0jj+PxSA7AM+RwxMBB4D GBoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=h2Q3dtiM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id mi5-20020a17090b4b4500b002468b3ff982si17796061pjb.121.2023.05.04.08.06.56; Thu, 04 May 2023 08:07:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=h2Q3dtiM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230350AbjEDO7d (ORCPT + 99 others); Thu, 4 May 2023 10:59:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230519AbjEDO7H (ORCPT ); Thu, 4 May 2023 10:59:07 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08AEA49DA for ; Thu, 4 May 2023 07:58:45 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-556011695d1so7667127b3.1 for ; Thu, 04 May 2023 07:58:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683212309; x=1685804309; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=FyjCHPBh44PN3ytyHlUnOM1ASgpqY1cxsBMty1tbu/M=; b=h2Q3dtiMAz5jAvOjfEHVY9ZA7j1QyQ6803OyYx4Pu17ci2sEWteu8ncbtegLvhtM3z zyOk45a71QSLyNnKQBRHprHb1Rw2yijPAd2tX+coUVnx6V8L7uorPPpiAeEpgE98A+Ee 5PwjCttFi/znmNl1oOtlqvba5bv7IZRJ+4WBDirEtT5NCvZSA+kbf6z3fuG+jykVqSKD HbxYGUWJN5+PFHCdQoAJFjiw2njnbj/M3wglMj0/2MWH7CqQ2RlYoCKR8k+iWiGmNRvD PY9ry6L9MoT87ezIzwLA0UUivnN8NagCOnQOmTyiG5z1xM1Fzh+eaGCTe6laa5VQzCdd 3X6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683212309; x=1685804309; 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=FyjCHPBh44PN3ytyHlUnOM1ASgpqY1cxsBMty1tbu/M=; b=Il63/eR3TEBhYY8b200mlOinDyDsDfc5mhP6kiLA6mJiPUhtUCl9hBl88OwaS39IAJ xmKccrM2p2TWUBNkvtCyN/Bup2+Vk4VxxmraWO0X9F2FdinaHAbb2HJfIiIjK87HA9mC yLqAKoCgIN4HW6cfE/skUCnXeUYWGEdNUNiwtRezLOoCcn4uwzRjhJL4NhyUbI3yrTvi vMBRoSh55EpIFwnu9MOi0EccP9tiRWDtRpjLnp2JETlaHXyG9R8vxiISrDBzFXQ65daA 3U4WV7W+fNmXXYZX0F5oAB45owFZjw1bjCdunc/AvppWERfrPsgdmLqDshGcuqI/ll/u bpaA== X-Gm-Message-State: AC+VfDyXcpBRcmj3RJ1DiNtCNJVWv4w2PYMmHmqljU9y/nAXeEk54m/y /lKyXfRqcASBFIVPKunwSjYKnbtD6BDTww== X-Received: from joychakr.c.googlers.com ([fda3:e722:ac3:cc00:4f:4b78:c0a8:6ea]) (user=joychakr job=sendgmr) by 2002:a81:ad21:0:b0:54f:a60c:12eb with SMTP id l33-20020a81ad21000000b0054fa60c12ebmr1423741ywh.1.1683212309438; Thu, 04 May 2023 07:58:29 -0700 (PDT) Date: Thu, 4 May 2023 14:57:36 +0000 In-Reply-To: <20230504145737.286444-1-joychakr@google.com> Mime-Version: 1.0 References: <20230504145737.286444-1-joychakr@google.com> X-Mailer: git-send-email 2.40.1.495.gc816e09b53d-goog Message-ID: <20230504145737.286444-7-joychakr@google.com> Subject: [PATCH 6/7] dmaengine: pl330: Quirk to use DMA singles for peripheral _dregs From: Joy Chakraborty To: Vinod Koul , Rob Herring , Krzysztof Kozlowski 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 Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add quirk "arm,pl330-periph-single-dregs" to use DMA singles in a loop to load/store the remaining bytes left after chucks of bursts are done which is handled by the _dregs() function. If the transfer length is not a multiple of (AxLen*AxSize) then the _dregs function takes care of setting up CCR with residual burst required to complete the transaction. It does so by changing the AxLen in CCR and 1 burst of Load and Store. But some peripherals might not set the burst request signal to the DMA controller since the number of bytes to transfer is less then the initial size of burst requested i.e. AxLen*AxSize leading to a forever wait. Example of such a case : Considering a peripheral having an RX FIFO of n bytes and a sw configurable threshold level logic which drives the RX burst req signal to PL330 i.e. when data in the RX fifo crosses the threshold value the peripheral asserts the RX burst request to PL330 to copy data from the fifo in bursts. Taking an example say the Rx Fifo is 256 bytes in depth, the max AxLen is 16, max AxSize is 4bytes and 304 bytes had to copied from peripheral to memory. In this case the peripheral SW driver would configure the threshold to the maximum possible burst size (AxLen*AxSize) i.e. 64 bytes and pass the same to pl330 driver using src/dst_maxburst variable. PL330 would copy the first 256 bytes with 4 burst transactions and the 48 remaining bytes would be handled by _dregs(). Currently _dregs() would setup a burst for AxLen=3 and AxSize=16 to copy the 48bytes but since 48bytes is below the threshold configured at the peripheral the Rx burst request signal would not get set leading to a forever wait and timeout. This quirk will copy the remaining 48bytes using single transactions of 4bytes each which would not depend on the burst req signal from the peripheral. Instructions generated for above example with quirk set: DMAMOV CCR 0xbd0239 DMAMOV SAR 0xffffe000 DMAMOV DAR 0xffffc860 DMALP_1 3 DMAFLUSHP 0 DMAWFPB 0 DMALDB DMASTPB 0 DMALPENDA_1 bjmpto_7 DMAMOV CCR 0xad0229 DMALDA DMALP_0 11 DMAFLUSHP 0 DMAWFPS 0 DMASTPS 0 DMALPENDA_0 bjmpto_6 DMASEV 3 DMAEND Signed-off-by: Joy Chakraborty --- drivers/dma/pl330.c | 74 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index b4933fab8a62..0b4e5390bace 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -36,6 +36,7 @@ #define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0) #define PL330_QUIRK_PERIPH_BURST BIT(1) #define PL330_QUIRK_OPTIMIZE_DEV2MEM_AXSIZE BIT(2) +#define PL330_QUIRK_PERIPH_SINGLE_DREGS BIT(3) enum pl330_cachectrl { CCTRL0, /* Noncacheable and nonbufferable */ @@ -524,6 +525,10 @@ static struct pl330_of_quirks { { .quirk = "arm,pl330-optimize-dev2mem-axsize", .id = PL330_QUIRK_OPTIMIZE_DEV2MEM_AXSIZE, + }, + { + .quirk = "arm,pl330-periph-single-dregs", + .id = PL330_QUIRK_PERIPH_SINGLE_DREGS, } }; @@ -1213,6 +1218,67 @@ static inline int _ldst_peripheral(struct pl330_dmac *pl330, return off; } +/* + * Sets up transfers to peripheral using DMA Singles instead of Bursts. + * Data is moved between fifo and memory in bursts following which it is + * loaded/stored to peripheral using Loops of DMA singles based on + * transfer direction. + */ +static inline int _ldst_periph_single_dregs(struct pl330_dmac *pl330, + unsigned int dry_run, u8 buf[], + const struct _xfer_spec *pxs, + int src_length, int dst_length) +{ + int off = 0; + unsigned int ljmp, lpcnt; + struct _arg_LPEND lpend; + enum dma_transfer_direction direction = pxs->desc->rqtype; + + if (direction == DMA_MEM_TO_DEV) { + off += _emit_load(dry_run, &buf[off], ALWAYS, direction, + pxs->desc->peri); + lpcnt = dst_length; + } else { + lpcnt = src_length; + } + + /* + * Use Loop Cnt 0 to load/store from/to peripheral in single transactions + * since Burst Req might not be set as pending transfer length maybe less + * size of bytes to burst (AxSize * AxLen). + */ + off += _emit_LP(dry_run, &buf[off], 0, lpcnt); + ljmp = off; + + /* + * do FLUSHP at beginning to clear any stale dma requests before the + * first WFP. + */ + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); + + off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri); + + if (direction == DMA_MEM_TO_DEV) + off += _emit_store(dry_run, &buf[off], SINGLE, direction, + pxs->desc->peri); + else + off += _emit_load(dry_run, &buf[off], SINGLE, direction, + pxs->desc->peri); + + lpend.cond = ALWAYS; + lpend.forever = false; + lpend.loop = 0; + lpend.bjump = off - ljmp; + off += _emit_LPEND(dry_run, &buf[off], &lpend); + + if (direction == DMA_DEV_TO_MEM) + off += _emit_store(dry_run, &buf[off], ALWAYS, direction, + pxs->desc->peri); + + return off; +} + static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], const struct _xfer_spec *pxs, int cyc) { @@ -1278,8 +1344,12 @@ static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], case DMA_MEM_TO_DEV: case DMA_DEV_TO_MEM: off += _emit_MOV(dry_run, &buf[off], CCR, dregs_ccr); - off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, 1, - BURST); + if (pl330->quirks & PL330_QUIRK_PERIPH_SINGLE_DREGS) + off += _ldst_periph_single_dregs(pl330, dry_run, &buf[off], + pxs, src_length, dst_length); + else + off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, 1, + BURST); break; case DMA_MEM_TO_MEM: -- 2.40.1.495.gc816e09b53d-goog