From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lf1-f48.google.com (mail-lf1-f48.google.com [209.85.167.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A55145107C for ; Thu, 26 Feb 2026 19:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.48 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772134705; cv=none; b=Ri5zxm6osPSqCBd2FYmC2JXQNUKeFbnzbDzYDD8VgKLUxGHBYBQO2wZPn0hPq03+EoCkMWjdZKDeMCkNTEywNc8kmJ566XL5cBVsGP8jvXcsZziDUHXZpWjmMgqEKUrDODBlmmRmfBVQ9YRDNBFuU/bVHDkkPhigrljszdk2lek= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772134705; c=relaxed/simple; bh=fjUa9EDlU3GuO7EKIKyPeJZwolOxnfN83FgyVCqmeVc=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=eqGczwmpRhFYrCv+xM4+YdzG/d6kMffrGmjAoy3bChzbHbCqbZWV3AbN02QMY7ncFbon8C+DTIekmwc1kij1srYbGOrVj9gBuYM9aDnX5djyjhpT2PyLHJ76jxl4gQY5KWwIPnCk4WiR/5WP13uCT+3aSh/xL6TClgICeXVW2FM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LhpY2xEj; arc=none smtp.client-ip=209.85.167.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LhpY2xEj" Received: by mail-lf1-f48.google.com with SMTP id 2adb3069b0e04-5a0ff30b240so1511514e87.0 for ; Thu, 26 Feb 2026 11:38:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772134699; x=1772739499; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:content-language:from :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=Ln/7jOAd0mq+qmA6pTYKQmtpks7jHYiU+Gg/M2EOX0w=; b=LhpY2xEjunMdiD8x4ZDEuYb6eeMwyfs5e12o1qb2oU1pcokbHExraBJz33cqs9qeN8 mhK3W6Omkzsj1LU+jjojq/UF/71xCsBgIbbeTqkxvBd4L6aBE8kbpZzHbjrk0x7QQU9s k4zguCTzi3qXLA3N1WMjZ04QcbblCxNSKQr+8DF5T7LrxHBfAwGEP9hojBUWWa9sLlQ7 tq7HdBlfv0DoIaJeu+mNsYfdKAxC1A8ObfMaublDd+1+vqax1IRnMXq7dvGeNrB5PPQZ XBk5IypMDaNPEUUDiHdkaVsv1kvVu3emHg1He5l5s8/ETfPq0lnE9E5kgkJZ3Gh7pmSI YPRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772134699; x=1772739499; h=content-transfer-encoding:in-reply-to:content-language:from :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Ln/7jOAd0mq+qmA6pTYKQmtpks7jHYiU+Gg/M2EOX0w=; b=bm2SrV0JFyEfMsxBZgZ5UY07ENMp58gfJX2vzYI6nQbKc+NWmINzjifVdM9WJIW5Uu yLqDiN1GuayxCzSKo6hTw/AjM5adxFZHj4FQTewZAhcRqG1aaz3nKQ0yMHTPtZoqN+z6 XuZKBdcWxXNGT7EYA2VI/hMTqdDu9laz3eRX7wen3ed5B/O/3ydBKrLO5A67YABwp60q 7UWAOAwBZ3CZX25h4FhRGP4BOO+Iof+t9vhuaaklm/2oGjibYlkWHWOdLd1uGkPVmwA5 yaoNd5o+QfVeoFn/cFxNJSVb1eo5p2Iuxc1qwo3mqgQRfQZjuKQhGCKxDdYeVpJMomRi No6w== X-Forwarded-Encrypted: i=1; AJvYcCVa+pnGc9drFaEm/pwMz3cn+r4lm1Lg8mFo2vlEYz96xQOXflQliYxLUwN5rMjr+fRs/CzTZIPeXlpEda0=@vger.kernel.org X-Gm-Message-State: AOJu0Yxn4F3PkOTq4TTFXqe7wiwJXLEk0NQIxZxXqLeFLcHAlseULSgX cz5EbllxVy3z4A3q5tVrZvMLoi33Et0bn1TrzEK5WD6yN3zlI2I3SpFv X-Gm-Gg: ATEYQzxGvme4QnDmoYHfnLr65Usx0ov7Mrp5kaX0ZCsHhvTkqc8odGBIX+fZoUOuUi/ 8eeJQ45y8MQMMpzSEDbQljYQWBKXHbEQOxx088zSG/dImoVc3F0TMQLj5/+LOyz0ia9plrEWxP5 awlFBn59sf5+2/wxcjXQRM6jt42Xy6AuBU/lbIILbJy55ctPBANA04YS0UvXVESzFlR15oVYoTB a1aJrj3ko1Cphf5pwvQe1GdQ1/sXLHSJ5dYwAccVPp1S8i3xuEY3qRv/Jv+LW7ZhIl377aPWL6t /zN1MKDox2Ukt49VKPg9SxFDZbLul7L6D6Nzc5kcZdMFB3PGPTgC8L9VmRV0I5NnsOaBia6GqrS 4ZDtorCNjMKXmf4GuS0cJ/0kII7F0+nKMQ7re3cBJpGeRANxhtFUuh5rAbJCWbygSg9SpGO0x0X ZpMEEn9fI0m+HtlVcYWF0qeyrwMhKUGk1NawS42/PQj1esxarjQDiToVBOiMlBoqqDicTOI20= X-Received: by 2002:ac2:4f0d:0:b0:59e:5fc4:26b2 with SMTP id 2adb3069b0e04-5a10ff299f2mr101372e87.0.1772134698984; Thu, 26 Feb 2026 11:38:18 -0800 (PST) Received: from [10.0.0.100] (host-185-69-74-59.kaisa-laajakaista.fi. [185.69.74.59]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5a10ff4341asm122617e87.39.2026.02.26.11.38.17 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 26 Feb 2026 11:38:17 -0800 (PST) Message-ID: <5c70a8d7-9215-46d3-bcd4-0837597fdda7@gmail.com> Date: Thu, 26 Feb 2026 21:39:44 +0200 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v5 15/18] dmaengine: ti: k3-udma-v2: New driver for K3 BCDMA_V2 To: Sai Sree Kartheek Adivi , vkoul@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, nm@ti.com, ssantosh@kernel.org, dmaengine@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, vigneshr@ti.com, Frank.li@nxp.com Cc: r-sharma3@ti.com, gehariprasath@ti.com References: <20260218095243.2832115-1-s-adivi@ti.com> <20260218095243.2832115-16-s-adivi@ti.com> From: =?UTF-8?Q?P=C3=A9ter_Ujfalusi?= Content-Language: en-US In-Reply-To: <20260218095243.2832115-16-s-adivi@ti.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 18/02/2026 11:52, Sai Sree Kartheek Adivi wrote: > Add support for BCDMA_V2. > > The BCDMA_V2 is different than the existing BCDMA supported by the > k3-udma driver. > > The changes in BCDMA_V2 are: > - Autopair: There is no longer a need for PSIL pair and AUTOPAIR bit > needs to set in the RT_CTL register. > - Static channel mapping: Each channel is mapped to a single peripheral. > - Direct IRQs: There is no INT-A and interrupt lines from DMA are > directly connected to GIC. > - Remote side configuration handled by DMA. So no need to write to PEER > registers to START / STOP / PAUSE / TEARDOWN. > - Unified Channel Space: Tx and Rx channels share a single register > space. Each channel index is specifically fixed in hardware as either > Tx or Rx in an interleaved manner. > > Also, since a version member is introduced in the match_data, Add > version v1 in match_data of SoCs using v1 DMA. > > Signed-off-by: Sai Sree Kartheek Adivi > --- > drivers/dma/ti/Kconfig | 14 +- > drivers/dma/ti/Makefile | 1 + > drivers/dma/ti/k3-udma-common.c | 86 +- > drivers/dma/ti/k3-udma-v2.c | 1283 +++++++++++++++++++++++++++++ > drivers/dma/ti/k3-udma.c | 9 + > drivers/dma/ti/k3-udma.h | 121 +-- > include/linux/soc/ti/k3-ringacc.h | 3 + > 7 files changed, 1446 insertions(+), 71 deletions(-) > create mode 100644 drivers/dma/ti/k3-udma-v2.c > > diff --git a/drivers/dma/ti/Kconfig b/drivers/dma/ti/Kconfig > index 712e456015459..40713bd1e8e9b 100644 > --- a/drivers/dma/ti/Kconfig > +++ b/drivers/dma/ti/Kconfig > @@ -49,6 +49,18 @@ config TI_K3_UDMA > Enable support for the TI UDMA (Unified DMA) controller. This > DMA engine is used in AM65x and j721e. > > +config TI_K3_UDMA_V2 > + tristate "Texas Instruments K3 UDMA v2 support" > + depends on ARCH_K3 > + select DMA_ENGINE > + select DMA_VIRTUAL_CHANNELS > + select TI_K3_UDMA_COMMON > + select TI_K3_RINGACC > + select TI_K3_PSIL > + help > + Enable support for the TI UDMA (Unified DMA) v2 controller. This > + DMA engine is used in AM62L. > + > config TI_K3_UDMA_COMMON > tristate > default n > @@ -63,7 +75,7 @@ config TI_K3_UDMA_GLUE_LAYER > > config TI_K3_PSIL > tristate > - default TI_K3_UDMA > + default TI_K3_UDMA || TI_K3_UDMA_V2 > > config TI_DMA_CROSSBAR > bool > diff --git a/drivers/dma/ti/Makefile b/drivers/dma/ti/Makefile > index 41bfba944dc6c..296aa3421e71b 100644 > --- a/drivers/dma/ti/Makefile > +++ b/drivers/dma/ti/Makefile > @@ -3,6 +3,7 @@ obj-$(CONFIG_TI_CPPI41) += cppi41.o > obj-$(CONFIG_TI_EDMA) += edma.o > obj-$(CONFIG_DMA_OMAP) += omap-dma.o > obj-$(CONFIG_TI_K3_UDMA) += k3-udma.o > +obj-$(CONFIG_TI_K3_UDMA_V2) += k3-udma-v2.o > obj-$(CONFIG_TI_K3_UDMA_COMMON) += k3-udma-common.o > obj-$(CONFIG_TI_K3_UDMA_GLUE_LAYER) += k3-udma-glue.o > k3-psil-lib-objs := k3-psil.o \ > diff --git a/drivers/dma/ti/k3-udma-common.c b/drivers/dma/ti/k3-udma-common.c > index 0ffc6becc402e..ff2b0353515ee 100644 > --- a/drivers/dma/ti/k3-udma-common.c > +++ b/drivers/dma/ti/k3-udma-common.c > @@ -171,8 +171,13 @@ bool udma_is_desc_really_done(struct udma_chan *uc, struct udma_desc *d) > uc->config.dir != DMA_MEM_TO_DEV || !(uc->config.tx_flags & DMA_PREP_INTERRUPT)) > return true; > > - peer_bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG); > - bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_BCNT_REG); > + if (uc->ud->match_data->version == K3_UDMA_V2) { Consider to start with V1? V3 might be similar to V2 and you save on churn in the future? Same comment for other version checks. > + peer_bcnt = udma_chanrt_read(uc, UDMA_CHAN_RT_PERIPH_BCNT_REG); > + bcnt = udma_chanrt_read(uc, UDMA_CHAN_RT_BCNT_REG); > + } else { > + peer_bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG); > + bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_BCNT_REG); > + } > > /* Transfer is incomplete, store current residue and time stamp */ > if (peer_bcnt < bcnt) { > @@ -319,6 +324,7 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, > size_t tr_size; > int num_tr = 0; > int tr_idx = 0; > + u32 extra_flags = 0; > u64 asel; > > /* estimate the number of TRs we will need */ > @@ -342,6 +348,11 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, > else > asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT; > > + if (uc->ud->match_data->type == DMA_TYPE_BCDMA && > + uc->ud->match_data->version == K3_UDMA_V2 && > + dir == DMA_MEM_TO_DEV) > + extra_flags = CPPI5_TR_CSF_EOP; > + > tr_req = d->hwdesc[0].tr_req_base; > for_each_sg(sgl, sgent, sglen, i) { > dma_addr_t sg_addr = sg_dma_address(sgent); > @@ -358,7 +369,7 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, > > cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1, false, > false, CPPI5_TR_EVENT_SIZE_COMPLETION, 0); > - cppi5_tr_csf_set(&tr_req[tr_idx].flags, CPPI5_TR_CSF_SUPR_EVT); > + cppi5_tr_csf_set(&tr_req[tr_idx].flags, CPPI5_TR_CSF_SUPR_EVT | extra_flags); > > sg_addr |= asel; > tr_req[tr_idx].addr = sg_addr; > @@ -372,7 +383,7 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, > false, false, > CPPI5_TR_EVENT_SIZE_COMPLETION, 0); > cppi5_tr_csf_set(&tr_req[tr_idx].flags, > - CPPI5_TR_CSF_SUPR_EVT); > + CPPI5_TR_CSF_SUPR_EVT | extra_flags); > > tr_req[tr_idx].addr = sg_addr + tr0_cnt1 * tr0_cnt0; > tr_req[tr_idx].icnt0 = tr1_cnt0; > @@ -2052,6 +2063,8 @@ int udma_get_tchan(struct udma_chan *uc) > uc->tchan = NULL; > return ret; > } > + if (ud->match_data->version == K3_UDMA_V2) > + uc->chan = uc->tchan; > > if (ud->tflow_cnt) { > int tflow_id; > @@ -2102,6 +2115,8 @@ int udma_get_rchan(struct udma_chan *uc) > uc->rchan = NULL; > return ret; > } > + if (ud->match_data->version == K3_UDMA_V2) > + uc->chan = uc->rchan; > > return 0; > } > @@ -2379,16 +2394,26 @@ int bcdma_setup_resources(struct udma_dev *ud) > > ud->bchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->bchan_cnt), > sizeof(unsigned long), GFP_KERNEL); > + bitmap_zero(ud->bchan_map, ud->bchan_cnt); > ud->bchans = devm_kcalloc(dev, ud->bchan_cnt, sizeof(*ud->bchans), > GFP_KERNEL); > ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), > sizeof(unsigned long), GFP_KERNEL); > + bitmap_zero(ud->tchan_map, ud->tchan_cnt); > ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans), > GFP_KERNEL); > - ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt), > - sizeof(unsigned long), GFP_KERNEL); > - ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans), > - GFP_KERNEL); > + if (ud->match_data->version == K3_UDMA_V2) { > + ud->rchan_map = ud->tchan_map; > + ud->rchans = ud->tchans; > + ud->chan_map = ud->tchan_map; > + ud->chans = ud->tchans; > + } else { > + ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt), > + sizeof(unsigned long), GFP_KERNEL); > + bitmap_zero(ud->rchan_map, ud->rchan_cnt); > + ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans), > + GFP_KERNEL); > + } > /* BCDMA do not really have flows, but the driver expect it */ > ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rchan_cnt), > sizeof(unsigned long), > @@ -2484,11 +2509,18 @@ int setup_resources(struct udma_dev *ud) > if (ret) > return ret; > > - ch_count = ud->bchan_cnt + ud->tchan_cnt + ud->rchan_cnt; > - if (ud->bchan_cnt) > - ch_count -= bitmap_weight(ud->bchan_map, ud->bchan_cnt); > - ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt); > - ch_count -= bitmap_weight(ud->rchan_map, ud->rchan_cnt); > + if (ud->match_data->version == K3_UDMA_V2) { I would probbaly check for V1 and leave the V2 as simple else - trusting that v3 will likely be closer to it than v1? > + ch_count = ud->bchan_cnt + ud->tchan_cnt; > + if (ud->bchan_cnt) > + ch_count -= bitmap_weight(ud->bchan_map, ud->bchan_cnt); > + ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt); > + } else { > + ch_count = ud->bchan_cnt + ud->tchan_cnt + ud->rchan_cnt; > + if (ud->bchan_cnt) > + ch_count -= bitmap_weight(ud->bchan_map, ud->bchan_cnt); > + ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt); > + ch_count -= bitmap_weight(ud->rchan_map, ud->rchan_cnt); > + } > if (!ch_count) > return -ENODEV; > > @@ -2510,15 +2542,25 @@ int setup_resources(struct udma_dev *ud) > ud->rflow_cnt)); > break; > case DMA_TYPE_BCDMA: > - dev_info(dev, > - "Channels: %d (bchan: %u, tchan: %u, rchan: %u)\n", > - ch_count, > - ud->bchan_cnt - bitmap_weight(ud->bchan_map, > - ud->bchan_cnt), > - ud->tchan_cnt - bitmap_weight(ud->tchan_map, > - ud->tchan_cnt), > - ud->rchan_cnt - bitmap_weight(ud->rchan_map, > - ud->rchan_cnt)); > + if (ud->match_data->version == K3_UDMA_V1) { > + dev_info(dev, > + "Channels: %d (bchan: %u, tchan: %u, rchan: %u)\n", > + ch_count, > + ud->bchan_cnt - bitmap_weight(ud->bchan_map, > + ud->bchan_cnt), > + ud->tchan_cnt - bitmap_weight(ud->tchan_map, > + ud->tchan_cnt), > + ud->rchan_cnt - bitmap_weight(ud->rchan_map, > + ud->rchan_cnt)); > + } else if (ud->match_data->version == K3_UDMA_V2) { > + dev_info(dev, > + "Channels: %d (bchan: %u, chan: %u)\n", > + ch_count, > + ud->bchan_cnt - bitmap_weight(ud->bchan_map, > + ud->bchan_cnt), > + ud->chan_cnt - bitmap_weight(ud->chan_map, > + ud->chan_cnt)); > + } if you have else if {} you do want to have plain else {} to handle cases when neither. CHeck for V1 and leave V2 for a plain else branch? Optionally if indentation is geting tight, just create a helper function to print this info. > break; > case DMA_TYPE_PKTDMA: > dev_info(dev, I think this and the series looks good, the only thing I would consider is to revers the V1/2 checks when it makes sense - future incarnations of UDMA might be closer to V2 than V1 and you save on maintanance headache. -- Péter