From nobody Mon Feb 9 10:54:16 2026 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (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 1AF4D330332 for ; Mon, 26 Jan 2026 10:32:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423525; cv=none; b=YW34Wa4FmdOw0Qm2BKHc+VOAY3ZmBawB1On5pozNcTBscCVU1bHjd/sdfj4LtUhOrSjXYNCok/5sqSGYiUhba+sMNcuo33+SdjCOhYkWDbL8kmdpbg8DL0n52Yf78bdEJoFC3U88Oyc8+1uGMonuBajvgpHZY7Y4UwNSQ1B73fk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423525; c=relaxed/simple; bh=b1BJqAn5r2bWkK4hYICDDw4hYAlP5B50ADdrRpoAUlY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DR2rA9dTRswjyzbG3idzvIhT7iqIPm2wq46ueQPelFtW4vGy3zqglaiFRpOpJyNIRVecj+ygrcS099NbkZCawHnlXsh3DPvtjC0liXqnpQ1YhPHop/tUKHfy5Wypd/FBgF+6KkxxtgQ3RHFka+0gB37iNvVdfT+vK3nCKoFMj6c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev; spf=pass smtp.mailfrom=tuxon.dev; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b=PlUe6Aew; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b="PlUe6Aew" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-4359108fd24so2543033f8f.2 for ; Mon, 26 Jan 2026 02:32:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1769423522; x=1770028322; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EB0+q6M4rfVt0Jwi/g6CvASE0XuyTwoIRTjo+xXQvwE=; b=PlUe6AewimgXfywGrHukUjhtsXRq7OH4Q8+gffXmqg8Egt5n52I0gLu/aZEGP7Y1US KBwQGBHUy5wd9TmCzbnvrNLnex/oW5cLi/ZTxAY5LKJ+T9mK36Lyps291PV4yED4bejA SWJI5LANTQRd/L6rWpP9urUx+OkYmHkkF5XuTYp9oX+dkfG/NMrB2BJ14YPcH6mbs/Sl Z9E1D/3DhQwCMik/XY17k/jvE84vifHuYYFvKJinCrgCf6QGwd1nK1aE+ohuvp61pYKz rBS4FieBzQpebrMFVzZOgUX4oSVH86fytROoxApyJlHnl7hsrEqTSfMAGpKROxI4M/sy qK3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769423522; x=1770028322; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=EB0+q6M4rfVt0Jwi/g6CvASE0XuyTwoIRTjo+xXQvwE=; b=bTzaBQR98Ow1vm8QDkWjtBGoBxkh9omCarAPojrdJ3aCtKkG0yGuEHrGa5GMCgF+s7 /A11k99gDfRk0uHyaPx6lUfEszdO3zByCGeCnAGps/nuk5lVDnkGR6OgcexsQbJedrbT saod0h0JCcgOGtwT4ZKKns+F26OmgrL7LRpaUjxNkSw3FDATsti3JDmiZS1VV611C9ya BUggFmS5fNqrTYv0FsBxoBx2Gz8Sd4HoaQNaYs+aRqe8XW0+uLZ9sdbwJNFiIdfRXRHk UsyerZEYpSGw7YcXhaJ8itjnJ6FVL9IsZu+IxQVs5h4t7yYsTT0X3ETxqRusxJU1SDF9 jL0g== X-Forwarded-Encrypted: i=1; AJvYcCXTIgXCx+d2LnWSZpTWSqIKoP9FmL1BXkCKPomo8QmVOLAPdn5eRkWQ7LA3dNCl2ik/QzU23iOb+oKL2T0=@vger.kernel.org X-Gm-Message-State: AOJu0Ywspe6JTMN45ILytxFsEk9Y6Pg6g0rLvIJtVFQLStD5fk9QUhw4 7ioE82j2UDWQ9T1/173AkE8JRA4JGpycCyEVE2/0ksahlVRTFGs87Qr7Gx6JgyawN04= X-Gm-Gg: AZuq6aLbUlqJoAMgodFzqAIk0njakHLUoxOAW0r3jbhZDEbeJbvsfjDituF7o4mZ7Eb t4/CYMDhVovY/Fds8EtH71cIBbanAcJt5T62BrdXQMV65aqbFgXyaI6IGVzNMiqMJxdLwgK2cv9 kbbcvYuJKBqmFVidbR544G+/mvmtTUD38Hs4E/iHsvcqJ2DDTk+Ih4FzKQj9xhqmnhiHsvzhm0a 107PiHjY6hgAtuqUgijSpvkIilRxQ5U/WafateU6KSFc4B2dRZW+INY4kOIJYPuGt/pZYiX1h/B e/6bMCPb6d8/al+z0wW2ABqGXMQ8ZT3xTrXFYgkyTEbZfMFM4JI24c57g68t+pbiEu79F6ow5+R rxu+J4xBSodHHVS8TPjLHMr7sRd8drpFWjYoriBczvrYoOiL27cI/Q/svmVhOLDRyRD13CPRCUk BrWC7wt0wvnbwgFFqubgzYLfvTWn3iMfm1J1zJu2o= X-Received: by 2002:a5d:5d09:0:b0:435:985c:48f8 with SMTP id ffacd0b85a97d-435ca39ad31mr6124120f8f.45.1769423522276; Mon, 26 Jan 2026 02:32:02 -0800 (PST) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.31]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435b1c246ecsm29715049f8f.10.2026.01.26.02.32.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jan 2026 02:32:01 -0800 (PST) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com Cc: claudiu.beznea@tuxon.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Claudiu Beznea Subject: [PATCH 1/7] dmaengine: sh: rz-dmac: Add enable status bit Date: Mon, 26 Jan 2026 12:31:49 +0200 Message-ID: <20260126103155.2644586-2-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> References: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Claudiu Beznea Add a status bitmask to struct rz_dmac_chan. This is currently stores only the enable status of the DMA channel and it is a preparatory commit for adding cyclic DMA support. Signed-off-by: Claudiu Beznea --- drivers/dma/sh/rz-dmac.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index 35124043ae02..95ed357f2b74 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -62,6 +62,14 @@ struct rz_dmac_desc { =20 #define to_rz_dmac_desc(d) container_of(d, struct rz_dmac_desc, vd) =20 +/** + * enum rz_dmac_chan_status: RZ DMAC channel status + * @RZ_DMAC_CHAN_STATUS_ENABLED: Channel is enabled + */ +enum rz_dmac_chan_status { + RZ_DMAC_CHAN_STATUS_ENABLED, +}; + struct rz_dmac_chan { struct virt_dma_chan vc; void __iomem *ch_base; @@ -73,6 +81,8 @@ struct rz_dmac_chan { dma_addr_t src_per_address; dma_addr_t dst_per_address; =20 + unsigned long status; + u32 chcfg; u32 chctrl; int mid_rid; @@ -302,6 +312,8 @@ static void rz_dmac_enable_hw(struct rz_dmac_chan *chan= nel) rz_dmac_ch_writel(channel, channel->chcfg, CHCFG, 1); rz_dmac_ch_writel(channel, CHCTRL_SWRST, CHCTRL, 1); rz_dmac_ch_writel(channel, chctrl, CHCTRL, 1); + + channel->status |=3D BIT(RZ_DMAC_CHAN_STATUS_ENABLED); } } =20 @@ -313,6 +325,8 @@ static void rz_dmac_disable_hw(struct rz_dmac_chan *cha= nnel) dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index); =20 rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1); + + channel->status &=3D ~BIT(RZ_DMAC_CHAN_STATUS_ENABLED); } =20 static void rz_dmac_set_dmars_register(struct rz_dmac *dmac, int nr, u32 d= mars) @@ -578,6 +592,9 @@ static int rz_dmac_terminate_all(struct dma_chan *chan) list_splice_tail_init(&channel->ld_active, &channel->ld_free); list_splice_tail_init(&channel->ld_queue, &channel->ld_free); vchan_get_all_descriptors(&channel->vc, &head); + + channel->status =3D 0; + spin_unlock_irqrestore(&channel->vc.lock, flags); vchan_dma_desc_free_list(&channel->vc, &head); =20 @@ -841,8 +858,7 @@ static int rz_dmac_device_pause(struct dma_chan *chan) =20 guard(spinlock_irqsave)(&channel->vc.lock); =20 - val =3D rz_dmac_ch_readl(channel, CHSTAT, 1); - if (!(val & CHSTAT_EN)) + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_ENABLED))) return 0; =20 rz_dmac_ch_writel(channel, CHCTRL_SETSUS, CHCTRL, 1); @@ -882,8 +898,10 @@ static void rz_dmac_irq_handle_channel(struct rz_dmac_= chan *channel) dev_err(dmac->dev, "DMAC err CHSTAT_%d =3D %08X\n", channel->index, chstat); =20 - scoped_guard(spinlock_irqsave, &channel->vc.lock) + scoped_guard(spinlock_irqsave, &channel->vc.lock) { rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1); + channel->status &=3D ~BIT(RZ_DMAC_CHAN_STATUS_ENABLED); + } return; } =20 --=20 2.43.0 From nobody Mon Feb 9 10:54:16 2026 Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) (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 3CDDD330D43 for ; Mon, 26 Jan 2026 10:32:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423528; cv=none; b=rukHK34LmAOsrK1GaSsh/NPQXxHEZ/fPD7mymUvtVLxMAdy8QXi25V8mFI/n4cwym4ha1LEtXV90N6iQN5R54T61HlETxv6tQuFbqSU8TxRecgrFGXbOVkUW9X+i3NmtG9At5uaoZjRd+qoXk+QYYT6nas7c3ReoozVxx7m914c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423528; c=relaxed/simple; bh=wTSw5rrByeywpyx4b28b6t68newYvzHr0oIdTZgnlTo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Zh4cghQNg8Gps8WpTie66g/AvIg1uTdsXKD0xGKWgOfYYyGvkYw4YI/fZsJOS8EW7RCe+fHKJXelv1GOZMhgZd8wxjm9n2rN9iQYqJgCkOgZpoOVY5NSlzYgFJNmcTIIs8m3hdM3AOxGwvixTZG2JDj4XhADfzlfDAv5fVE+cpM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev; spf=pass smtp.mailfrom=tuxon.dev; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b=CGQQtia/; arc=none smtp.client-ip=209.85.221.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b="CGQQtia/" Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-42fb2314f52so2466414f8f.0 for ; Mon, 26 Jan 2026 02:32:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1769423524; x=1770028324; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=28LJKOzZr0ga3QymY5qs2v0wCcRNeHJMj2ha9kW7dhM=; b=CGQQtia/yGqo1RzFvOAcEJ0DGUf1TSVm/seO+wYRE1X/fXwDJ1GQZv+B7YkUZeaCtZ RyXG1R7457kAFOnZjNti1M9b5ZGCCJ3smcOlNhzpLUuwgcW8fj6yyU8ZipBHXlz+RndZ Idx52vFSCVDIsqUxQq4iW9062c7QyZgMl+nIe6EWxP58fnl+syUTB3v9KvK/ic8ZMY57 Je1P7TfymdMnPTTmpyxHbAfXc7uRjX92zoMFmWeonrlYdLCsyZ6/FxkXAHgLINcGNhAa ac0TeTRFfzXVGEm61KFUMRf0q0WLh+RS6cuAp2Jj5hbt7S2jvMoRXCCALuU2Ps2Mm5WO J7hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769423524; x=1770028324; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=28LJKOzZr0ga3QymY5qs2v0wCcRNeHJMj2ha9kW7dhM=; b=dorgagB8LLHSit6oZcgrcFu4qAMjex8tFpMTa4Twtpt5GjzYNe7GeAlDFk/HkrypeE EdWSj2eORDuoTlKDbN0wQwwIHmdaK8FpFPjNGX76R9fAYCdoA81DRptnm6wRikN1lMH6 1J0iqbQbes7HNU2hdQIEIhhZYPZ2IrtnMTlOkeBE0sCtdGcx8mVYFXd4xkl0bNc6w/1z /jdo6PB1heMULm/9bhYMQzq/qcep4fEw1jZVTHfMz61d+532u6/ksvbUxM2ETw0R+1rG RyQPjlflpuZWLrNVR/1REszcN16sbyPCzzf+KmuloZbL0O8upJyjhVtdmQpZuGNNo5lL 8+Rg== X-Forwarded-Encrypted: i=1; AJvYcCUf9EHX+cZof5RC+Ux0Beqr2c5HtpowaCU1gZVTIdGQzQaCN6Fb7dU0mK3c5QRLqty9CbgNqemCtluqwRc=@vger.kernel.org X-Gm-Message-State: AOJu0Yz17/Nl8U2p7rC1NWSDwPQ7sdrG7j3SHFyF9ytiEyqQFFk0c9jz 0wFcvR46MaRrXYYHRoYmBEUC7ugGENlXKZL/gWn2YaJSEvQ71z/hTcJs5FjW1dtcaSQ= X-Gm-Gg: AZuq6aJdTnxf5GOwsVk4x0ofT9+F2AaDWTa8CnETOFgCrSDHQy1fwCEcxJKuVAjKnQU +nJ7/M9foJ/SbCFS0JzPishcihG7ulT8bKJ52i4MSXe81ahXxHr5CHzg/YJyOE2edrDVjK8PY+O ylcEcNSwY76CGTeLDOc40RL/kZZc+K0W/OJSt1iBjrbdQ8X8MzNXtbU94BaQk/cxNMXzyP2l/3f v2YP3aJdCalcpGD7SiGhSL9HHme56fkncmaUCF/U4spoTibKEfuH+Rz/i8MDET3H3j4bS4xFMC9 NTPEEKQ7CrJECDOC+GWjbneV1S2hrle3WR1PDV8g/Ad2K+IG52pKbLQAfpt8Gww/pl0plq3XbBF dBNcp4wJ/pZliJdy8sFnQOpdEpf7B55QAQjHoBCRrmgaLx/bbt8BKYylbpEHHuNEGFheRQuGIbq oNhtm2vXAggrwgcplti5vL3yk/2/xQrdHr+sISYE8= X-Received: by 2002:a5d:5850:0:b0:435:a258:76e with SMTP id ffacd0b85a97d-435ca3a93d0mr6619369f8f.60.1769423524419; Mon, 26 Jan 2026 02:32:04 -0800 (PST) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.31]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435b1c246ecsm29715049f8f.10.2026.01.26.02.32.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jan 2026 02:32:04 -0800 (PST) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com Cc: claudiu.beznea@tuxon.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Claudiu Beznea Subject: [PATCH 2/7] dmaengine: sh: rz-dmac: Add pause status bit Date: Mon, 26 Jan 2026 12:31:50 +0200 Message-ID: <20260126103155.2644586-3-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> References: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Claudiu Beznea Add the RZ_DMAC_CHAN_STATUS_PAUSED status bit index. This is needed to implement suspend to RAM support for cyclic DMA channels, which will be added in subsequent commits. The pause and resume implementations are updated to reuse the code added for suspend to RAM handling. Since the pause state is now stored in a per-channel software cache, there is no longer a need to interrogate the hardware registers in the pause path. Using the software status cache simplifies the implementation. The resume code was updated to use the software status cache as well. This is a preparatory commit for cyclic DMA suspend to RAM support. Signed-off-by: Claudiu Beznea --- drivers/dma/sh/rz-dmac.c | 68 ++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index 95ed357f2b74..8d8391a5b3a7 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -65,9 +66,11 @@ struct rz_dmac_desc { /** * enum rz_dmac_chan_status: RZ DMAC channel status * @RZ_DMAC_CHAN_STATUS_ENABLED: Channel is enabled + * @RZ_DMAC_CHAN_STATUS_PAUSED: Channel is paused though DMA engine callba= cks */ enum rz_dmac_chan_status { RZ_DMAC_CHAN_STATUS_ENABLED, + RZ_DMAC_CHAN_STATUS_PAUSED, }; =20 struct rz_dmac_chan { @@ -833,12 +836,9 @@ static enum dma_status rz_dmac_tx_status(struct dma_ch= an *chan, return status; =20 scoped_guard(spinlock_irqsave, &channel->vc.lock) { - u32 val; - residue =3D rz_dmac_chan_get_residue(channel, cookie); =20 - val =3D rz_dmac_ch_readl(channel, CHSTAT, 1); - if (val & CHSTAT_SUS) + if (channel->status & BIT(RZ_DMAC_CHAN_STATUS_PAUSED)) status =3D DMA_PAUSED; } =20 @@ -851,35 +851,71 @@ static enum dma_status rz_dmac_tx_status(struct dma_c= han *chan, return status; } =20 -static int rz_dmac_device_pause(struct dma_chan *chan) +static int rz_dmac_device_pause_set(struct rz_dmac_chan *channel, + enum rz_dmac_chan_status status) { - struct rz_dmac_chan *channel =3D to_rz_dmac_chan(chan); u32 val; + int ret; =20 - guard(spinlock_irqsave)(&channel->vc.lock); + lockdep_assert_held(&channel->vc.lock); =20 if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_ENABLED))) return 0; =20 rz_dmac_ch_writel(channel, CHCTRL_SETSUS, CHCTRL, 1); - return read_poll_timeout_atomic(rz_dmac_ch_readl, val, - (val & CHSTAT_SUS), 1, 1024, - false, channel, CHSTAT, 1); + ret =3D read_poll_timeout_atomic(rz_dmac_ch_readl, val, + (val & CHSTAT_SUS), 1, 1024, false, + channel, CHSTAT, 1); + if (ret) + return ret; + + channel->status |=3D BIT(status); + + return 0; } =20 -static int rz_dmac_device_resume(struct dma_chan *chan) +static int rz_dmac_device_pause(struct dma_chan *chan) { struct rz_dmac_chan *channel =3D to_rz_dmac_chan(chan); - u32 val; =20 guard(spinlock_irqsave)(&channel->vc.lock); =20 - /* Do not check CHSTAT_SUS but rely on HW capabilities. */ + if (channel->status & BIT(RZ_DMAC_CHAN_STATUS_PAUSED)) + return 0; + + return rz_dmac_device_pause_set(channel, RZ_DMAC_CHAN_STATUS_PAUSED); +} + +static int rz_dmac_device_resume_set(struct rz_dmac_chan *channel, + enum rz_dmac_chan_status status) +{ + u32 val; + int ret; + + lockdep_assert_held(&channel->vc.lock); + + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_PAUSED))) + return 0; =20 rz_dmac_ch_writel(channel, CHCTRL_CLRSUS, CHCTRL, 1); - return read_poll_timeout_atomic(rz_dmac_ch_readl, val, - !(val & CHSTAT_SUS), 1, 1024, - false, channel, CHSTAT, 1); + ret =3D read_poll_timeout_atomic(rz_dmac_ch_readl, val, + !(val & CHSTAT_SUS), 1, 1024, false, + channel, CHSTAT, 1); + if (ret) + return ret; + + channel->status &=3D ~BIT(status); + + return 0; +} + +static int rz_dmac_device_resume(struct dma_chan *chan) +{ + struct rz_dmac_chan *channel =3D to_rz_dmac_chan(chan); + + guard(spinlock_irqsave)(&channel->vc.lock); + + return rz_dmac_device_resume_set(channel, RZ_DMAC_CHAN_STATUS_PAUSED); } =20 /* --=20 2.43.0 From nobody Mon Feb 9 10:54:16 2026 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.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 6AE26331223 for ; Mon, 26 Jan 2026 10:32:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423531; cv=none; b=nWG1srvT0o3r4PzZGiWeE0Fv66krYph6TkB2c05yl0fVCeRRBNMjW9d8Z94Der6n2L0+W9czP6vHg8jw/Kf1+hC8LvghE0Ue8KNfsDVhVaI7WN0DF6FdXu3UE6ZuQM9wmQ4tb17eNt1QE6g+WXeopBGZ//8ygLnh54v2uQ64yks= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423531; c=relaxed/simple; bh=r/SU5oimCuoe+JcHi0XUqVFDCGGG+2pEiPjSeS+Fvhw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lFyPIB9yR6bI3vet9SmnuBydkvrU4O/6c8j+NPufxqZMItzH1ert/Ng9DnCI6Kt0RGPx17c7NAQ1fzkuYchVqV2NCt870hNEGlswI2A4YHucHoeuhPe4VMeIIr3xs2Ry9D5UtQniRV3Xa3dWwzA33VflmwY6ECbvkP6kb4SMZhg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev; spf=pass smtp.mailfrom=tuxon.dev; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b=HwlYUNH3; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b="HwlYUNH3" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-42fbc544b09so3061526f8f.1 for ; Mon, 26 Jan 2026 02:32:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1769423527; x=1770028327; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nWa0aGJtSMtx7LCzliIPZcMgkE6x5phxxbaj/EtOLPo=; b=HwlYUNH3Wn+odahPefogz6BXJ3wnDaNVajiYnyDjhjToqMIKq4UMP51TmP05SWISDf 0dWNHkB1yrQijuTSmDsAWPZOZZb5L7d2AuO6Z95fvVF9b8TBUuO0Uit5S68YNrWroLyD iLvqdxs41ehk/os9QuSVIZ1PBPn8DI5PYOJrWc7zG3XBwR+l8g7Awnwi5pRv3sV3hoTb 8O2TK0XrfFT1TqPR85Z4mEXslHKomILN/B7O0q6DQpfwG52iXJ4HL1xtn5wtbrbMFUo0 BxwlR0zm3X1YIDJHhBramH49UGC53nKLXsw99J4EH/8EmoLbKvJKrkV9JAG9Q53I+tqj DU5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769423527; x=1770028327; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=nWa0aGJtSMtx7LCzliIPZcMgkE6x5phxxbaj/EtOLPo=; b=LIUEJQGBPkm4grSHsxcLUdPS4Q7lrx9OL+OfHxSwdYYSYUeFevZRxKtu9xzegrbO6Z iklI7ta4htvjKRZVwz9JSSIqmSqVJx4HzNv+tcVvQlPP0Ow3NYZ1XJhmascNqivjYMgV uZym8dyNMde586RBZXakqWhQyGjn65F7TcDXhJYwoJaRf6IUQlHjBcjh7ZlwMaJ0oiMX vLaV8YeR3bi3KXsrBLfFO90hkrLIfBYAfJ/MOXA1n1mYiWrfll2yx8vURHYA3laMD11A zG8geH/edqV4s6f7dv7CFjjFsYGELnRm1JmG1mGq5XmsAUXhLDRqFykivKr/twSb0+Sj ShrA== X-Forwarded-Encrypted: i=1; AJvYcCVnAJX01WyyXC1v2CNi7sj1Rn7tm8AOHcAEocsQIhV99kQ+W3ve1iR/4T2aexmACqkuHjuRaMID25Ej/9I=@vger.kernel.org X-Gm-Message-State: AOJu0Yyw8UmIlixDSlks6Wh2KKfc9kCWsr+Y0mA9AG8n9IZ5LGH5OgID MhPPCAxt7M+2kpaU1DODiWeh46BAAW8qFnXH0bTLHhixTEQeBFTmyg4Hxio3Qp8wTwM= X-Gm-Gg: AZuq6aK2XvEP2B66tkrkt0oXn6BoE5sEbHwJt5BNoLQelVMZWe3ipc5MVdnt2LPV4VJ IVZECDjCDObb4O+CTnVD0abqDi1ijaOV5vG7VwRbV+jtBdAxRpbhTnmm4CRnexiUJoKTan0SUwL /wbuUmDh0VTkCOxE6Z7PC3RBmqM3NlnsZsemd5nj7WO+qD+9bfiGnoiWI34P16XuQU3kRyU2hDG UXWuN5E8Qh2f2X36y6dBGgQi8V67KZyNPIrQHztGaR0MglL02lXWZ0B2S2UgZk/ovC0qBDA2mnt hxtLLto2c7z05Vgnw9L36cZC1Bak2NERyEwyCvWlKEkRCBDLwn+QNu2dBKsK3t2JQwwpWwIqaqq HVFuX091f3YfQ8Npi/Ve9XswUagba9oN0hxNGSNpEXfMrORYgY4ag3JfcUWJdiXc3BtLguEsDn5 LwxQtX4lQAvNfjN4pha3wlK0+mtCMqjtsIsg/pw6c= X-Received: by 2002:a05:6000:24c1:b0:433:1d30:44c with SMTP id ffacd0b85a97d-435ca138ae8mr6980335f8f.43.1769423526727; Mon, 26 Jan 2026 02:32:06 -0800 (PST) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.31]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435b1c246ecsm29715049f8f.10.2026.01.26.02.32.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jan 2026 02:32:06 -0800 (PST) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com Cc: claudiu.beznea@tuxon.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Claudiu Beznea Subject: [PATCH 3/7] dmaengine: sh: rz-dmac: Drop the update of CHCTRL_SETEN in channel->chctrl APIs Date: Mon, 26 Jan 2026 12:31:51 +0200 Message-ID: <20260126103155.2644586-4-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> References: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Claudiu Beznea The CHCTRL_SETEN bit is explicitly set in rz_dmac_enable_hw(). Updating struct rz_dmac_chan::chctrl with this bit is unnecessary in the current code base. Moreover, it conflicts with the configuration sequence used for cyclic DMA channels during suspend to RAM, which will be introduced in subsequent commits. This is a preparatory commit for cyclic DMA suspend to RAM support. Signed-off-by: Claudiu Beznea --- drivers/dma/sh/rz-dmac.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index 8d8391a5b3a7..4bc7ea9566fd 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -375,7 +375,7 @@ static void rz_dmac_prepare_desc_for_memcpy(struct rz_d= mac_chan *channel) rz_dmac_set_dma_req_no(dmac, channel->index, dmac->info->default_dma_req_= no); =20 channel->chcfg =3D chcfg; - channel->chctrl =3D CHCTRL_STG | CHCTRL_SETEN; + channel->chctrl =3D CHCTRL_STG; } =20 static void rz_dmac_prepare_descs_for_slave_sg(struct rz_dmac_chan *channe= l) @@ -424,8 +424,6 @@ static void rz_dmac_prepare_descs_for_slave_sg(struct r= z_dmac_chan *channel) channel->lmdesc.tail =3D lmdesc; =20 rz_dmac_set_dma_req_no(dmac, channel->index, channel->mid_rid); - - channel->chctrl =3D CHCTRL_SETEN; } =20 static int rz_dmac_xfer_desc(struct rz_dmac_chan *chan) --=20 2.43.0 From nobody Mon Feb 9 10:54:16 2026 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (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 0665A331221 for ; Mon, 26 Jan 2026 10:32:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423533; cv=none; b=JWjHYPzJRabGpHn6pO2ZZsWFRg5ZEqbQpmvadxO6n/BzVv20wY3bjJ7Xdaloe9CAIuI9naEj7CDirD+F0l9cZOPq7k/a9YfqIbq6RXHn+Ake5jXBkyf4BbdWltZldvYYLp7JcU48elKtyKVgRwcUxzLa+75vAAY3QRYYzSE+HSM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423533; c=relaxed/simple; bh=FDjnF4UpSTEPXJyCUdbDCAy/0GBL/PqeHCzZosK9sC4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u0CT+H6PhxS6FD7Vjwb6Z7t01Wdnj4AyBTYxWU7DXkl/IhXnsWOxVuGkpg3yrjoSyW4E18aGbMfWOd7q3jcgskA7oEzbfX7C0hdUpkDDjyYYR6NH0EtZsUFqej452Q1OQmXtsC78Zj/XbgJass0B4GLPeFzCw4ztJ1Yam+pgqjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev; spf=pass smtp.mailfrom=tuxon.dev; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b=qCAFhOT/; arc=none smtp.client-ip=209.85.221.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b="qCAFhOT/" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-42fbc305882so2579580f8f.0 for ; Mon, 26 Jan 2026 02:32:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1769423529; x=1770028329; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=80qOpgFk0DdjKJ6kD9DW3n53HU5v2XYf93zHUR/W1S0=; b=qCAFhOT/+Ce/FkmRiwIf2a2KDA7BwW36bF/TX5gzIbqevuCpVd9HzKu7m5fzGd5t9U ft0bhih/T7rsZUNsspc3Pi4CEkg6mODn/gq9HK6KwLJMXRZ5BUIOWUWmL9HInnEMa1IV kMNiNKeH8KQ/D2bfG6G8yyqXGf75eZNdBDJL5d+w7hCyOyS6Mc1Q8VgyLgIJzkpQaYE1 p4YmH17MvGPsqy8wVBm2KMgXpuQ7X8gW6IhNm4BBi/o+GQM00FyxJwiFy5gNcgXB8l5M uK7uxWoeWaY4TykkS8/EXz36qFtQC/HZ6xl+UAtZNPdqInDsy37KtqPTl1okVQ+1BiEz Lsfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769423529; x=1770028329; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=80qOpgFk0DdjKJ6kD9DW3n53HU5v2XYf93zHUR/W1S0=; b=YQyuGja5xYfHQptK2Iz41jWrHYSvNgza+rngiA0/VMyQ/hoJKvTLoDVuTpuE1nJeph Sp3I3d4JWCCWBpHJEMivU1tNudI1NWrBRcD2iXC7I7RwXxuzpD4ERM3A4+gocPsuCkTm 3rhQR0dpFdZ66zu/KYLoJjvNqntAXcGXq7NWv3ZInGMPXYLvUAIZ/LvT8mnSgTQqkrjN qhBn6dE4iLtVtqOGo4wcS1gqf6Di9Je2A46rzlf4sWF1X9QSBc+fK0NOj/PbUOiv+gvo GR9z2ciE9vAD8cSn9heHOPOvbqj0GLFlAYo2W9owFlOet1IVl74BvOefvEjK5xBKcrZU oXfg== X-Forwarded-Encrypted: i=1; AJvYcCVADrfrf6OxCawbzTa8K6dEpn9B08ywzPOXLGam0J/p8GWC5MbBmKFlSKIYNS8M6cdPs/R3sAwcVujcHoA=@vger.kernel.org X-Gm-Message-State: AOJu0YwWdLT7r1jZqEhsbldmcYkjc5GW3sbS3iHv5EklhoI0RXs4LJK3 udkjpLXO/bfUv0d0+j58qvuPDiivkW4k6zfA58l1iZE12jiJOobWW+UrPWBWKqbgNGU= X-Gm-Gg: AZuq6aKJ3YnMzFm9v6zs5T1CpQNGS2WFXzF/JvR1/G1eAfbGZod9byyvkWl0g9D7z3m 3AQQEcEy7cFgDTdS8759G94CHGXEaW4JWrZm+TzemqlAmtp7ZY/ylrI3VAXujClMDiaX8A1dq5c Yh3kTBeoYzo3s28psjwuGQ6K6LS0IJpZFAjif8O3ALql9dXZfIxGBZmPDZYQmY00bkB3NlGvg9m UARro2h+81TcVqpNspnYPS7Ctakw5HHP+tMulqN1ULMr07ZhrWoAKEjam7VX8/Iv9DBSWi3I+MV 81r8Njd/FKEBHKTc+gQclkuAnrcoyaFOgxGyEeeQs+YZoUEUmwaxRXjByIsGCcNnGB9n8BTgvCY RWpB1+bFMD+bLP2GMXqDX2P2Mt2/EYJkXeoa0r5BRzOfWLTQlLiAkBa34EnLxVtlSJuLYN7zNjl rDVMUpipz8BcSTANGN8r7mblInsaJRW64BeYASJEckHBXvYSCgIQ== X-Received: by 2002:a05:6000:2c03:b0:434:24e2:bed7 with SMTP id ffacd0b85a97d-435ca0dd3d2mr5726046f8f.13.1769423528627; Mon, 26 Jan 2026 02:32:08 -0800 (PST) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.31]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435b1c246ecsm29715049f8f.10.2026.01.26.02.32.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jan 2026 02:32:08 -0800 (PST) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com Cc: claudiu.beznea@tuxon.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Claudiu Beznea Subject: [PATCH 4/7] dmaengine: sh: rz-dmac: Add cyclic DMA support Date: Mon, 26 Jan 2026 12:31:52 +0200 Message-ID: <20260126103155.2644586-5-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> References: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Claudiu Beznea Add cyclic DMA support to the RZ DMAC driver. A per-channel status bit is introduced to mark cyclic channels and is set during the DMA prepare callback. The IRQ handler checks this status bit and calls vchan_cyclic_callback() accordingly. Signed-off-by: Claudiu Beznea --- drivers/dma/sh/rz-dmac.c | 137 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 133 insertions(+), 4 deletions(-) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index 4bc7ea9566fd..ab5f49a0b9f2 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -35,6 +35,7 @@ enum rz_dmac_prep_type { RZ_DMAC_DESC_MEMCPY, RZ_DMAC_DESC_SLAVE_SG, + RZ_DMAC_DESC_CYCLIC, }; =20 struct rz_lmdesc { @@ -59,6 +60,7 @@ struct rz_dmac_desc { /* For slave sg */ struct scatterlist *sg; unsigned int sgcount; + u32 start_lmdesc; }; =20 #define to_rz_dmac_desc(d) container_of(d, struct rz_dmac_desc, vd) @@ -67,10 +69,12 @@ struct rz_dmac_desc { * enum rz_dmac_chan_status: RZ DMAC channel status * @RZ_DMAC_CHAN_STATUS_ENABLED: Channel is enabled * @RZ_DMAC_CHAN_STATUS_PAUSED: Channel is paused though DMA engine callba= cks + * @RZ_DMAC_CHAN_STATUS_CYCLIC: Channel is cyclic */ enum rz_dmac_chan_status { RZ_DMAC_CHAN_STATUS_ENABLED, RZ_DMAC_CHAN_STATUS_PAUSED, + RZ_DMAC_CHAN_STATUS_CYCLIC, }; =20 struct rz_dmac_chan { @@ -194,6 +198,7 @@ struct rz_dmac { =20 /* LINK MODE DESCRIPTOR */ #define HEADER_LV BIT(0) +#define HEADER_WBD BIT(2) =20 #define RZ_DMAC_MAX_CHAN_DESCRIPTORS 16 #define RZ_DMAC_MAX_CHANNELS 16 @@ -426,6 +431,60 @@ static void rz_dmac_prepare_descs_for_slave_sg(struct = rz_dmac_chan *channel) rz_dmac_set_dma_req_no(dmac, channel->index, channel->mid_rid); } =20 +static void rz_dmac_prepare_descs_for_cyclic(struct rz_dmac_chan *channel) +{ + struct dma_chan *chan =3D &channel->vc.chan; + struct rz_dmac *dmac =3D to_rz_dmac(chan->device); + struct rz_dmac_desc *d =3D channel->desc; + size_t period_len =3D d->sgcount; + struct rz_lmdesc *lmdesc; + size_t buf_len =3D d->len; + size_t periods =3D buf_len / period_len; + u32 start_lmdesc; + + lockdep_assert_held(&channel->vc.lock); + + channel->chcfg |=3D CHCFG_SEL(channel->index) | CHCFG_DMS; + + if (d->direction =3D=3D DMA_DEV_TO_MEM) { + channel->chcfg |=3D CHCFG_SAD; + channel->chcfg &=3D ~CHCFG_REQD; + } else { + channel->chcfg |=3D CHCFG_DAD | CHCFG_REQD; + } + + lmdesc =3D channel->lmdesc.tail; + start_lmdesc =3D channel->lmdesc.base_dma + + (sizeof(struct rz_lmdesc) * (lmdesc - channel->lmdesc.base)); + d->start_lmdesc =3D start_lmdesc; + + for (size_t i =3D 0; i < periods; i++) { + if (d->direction =3D=3D DMA_DEV_TO_MEM) { + lmdesc->sa =3D d->src; + lmdesc->da =3D d->dest + (i * period_len); + } else { + lmdesc->sa =3D d->src + (i * period_len); + lmdesc->da =3D d->dest; + } + + lmdesc->tb =3D period_len; + lmdesc->chitvl =3D 0; + lmdesc->chext =3D 0; + lmdesc->chcfg =3D channel->chcfg; + lmdesc->header =3D HEADER_LV | HEADER_WBD; + + if (i =3D=3D periods - 1) + lmdesc->nxla =3D start_lmdesc; + + if (++lmdesc >=3D (channel->lmdesc.base + DMAC_NR_LMDESC)) + lmdesc =3D channel->lmdesc.base; + } + + channel->lmdesc.tail =3D lmdesc; + + rz_dmac_set_dma_req_no(dmac, channel->index, channel->mid_rid); +} + static int rz_dmac_xfer_desc(struct rz_dmac_chan *chan) { struct rz_dmac_desc *d =3D chan->desc; @@ -446,6 +505,10 @@ static int rz_dmac_xfer_desc(struct rz_dmac_chan *chan) rz_dmac_prepare_descs_for_slave_sg(chan); break; =20 + case RZ_DMAC_DESC_CYCLIC: + rz_dmac_prepare_descs_for_cyclic(chan); + break; + default: return -EINVAL; } @@ -580,6 +643,52 @@ rz_dmac_prep_slave_sg(struct dma_chan *chan, struct sc= atterlist *sgl, return vchan_tx_prep(&channel->vc, &desc->vd, flags); } =20 +static struct dma_async_tx_descriptor * +rz_dmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, + size_t buf_len, size_t period_len, + enum dma_transfer_direction direction, + unsigned long flags) +{ + struct rz_dmac_chan *channel =3D to_rz_dmac_chan(chan); + size_t periods =3D buf_len / period_len; + struct rz_dmac_desc *desc; + + if (!is_slave_direction(direction)) + return NULL; + + if (periods > DMAC_NR_LMDESC) + return NULL; + + scoped_guard(spinlock_irqsave, &channel->vc.lock) { + if (list_empty(&channel->ld_free)) + return NULL; + + if (channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC)) + return NULL; + + channel->status |=3D BIT(RZ_DMAC_CHAN_STATUS_CYCLIC); + + desc =3D list_first_entry(&channel->ld_free, struct rz_dmac_desc, node); + + desc->type =3D RZ_DMAC_DESC_CYCLIC; + desc->sgcount =3D period_len; + desc->len =3D buf_len; + desc->direction =3D direction; + + if (direction =3D=3D DMA_DEV_TO_MEM) { + desc->src =3D channel->src_per_address; + desc->dest =3D buf_addr; + } else { + desc->src =3D buf_addr; + desc->dest =3D channel->dst_per_address; + } + + list_move_tail(channel->ld_free.next, &channel->ld_queue); + } + + return vchan_tx_prep(&channel->vc, &desc->vd, flags); +} + static int rz_dmac_terminate_all(struct dma_chan *chan) { struct rz_dmac_chan *channel =3D to_rz_dmac_chan(chan); @@ -731,9 +840,18 @@ static u32 rz_dmac_calculate_residue_bytes_in_vd(struc= t rz_dmac_chan *channel) } =20 /* Calculate residue from next lmdesc to end of virtual desc */ - while (lmdesc->chcfg & CHCFG_DEM) { - residue +=3D lmdesc->tb; - lmdesc =3D rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc); + if (channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC)) { + struct rz_dmac_desc *desc =3D channel->desc; + + while (lmdesc->nxla !=3D desc->start_lmdesc) { + residue +=3D lmdesc->tb; + lmdesc =3D rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc); + } + } else { + while (lmdesc->chcfg & CHCFG_DEM) { + residue +=3D lmdesc->tb; + lmdesc =3D rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc); + } } =20 dev_dbg(dmac->dev, "%s: VD residue is %u\n", __func__, residue); @@ -972,7 +1090,15 @@ static irqreturn_t rz_dmac_irq_handler_thread(int irq= , void *dev_id) } =20 desc =3D list_first_entry(&channel->ld_active, struct rz_dmac_desc, node); - vchan_cookie_complete(&desc->vd); + + if (channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC)) { + desc =3D channel->desc; + vchan_cyclic_callback(&desc->vd); + goto out; + } else { + vchan_cookie_complete(&desc->vd); + } + list_move_tail(channel->ld_active.next, &channel->ld_free); if (!list_empty(&channel->ld_queue)) { desc =3D list_first_entry(&channel->ld_queue, struct rz_dmac_desc, @@ -1239,6 +1365,8 @@ static int rz_dmac_probe(struct platform_device *pdev) engine =3D &dmac->engine; dma_cap_set(DMA_SLAVE, engine->cap_mask); dma_cap_set(DMA_MEMCPY, engine->cap_mask); + dma_cap_set(DMA_CYCLIC, engine->cap_mask); + engine->directions =3D BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); engine->residue_granularity =3D DMA_RESIDUE_GRANULARITY_BURST; rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_0_7_COMMON_BASE + DCTRL); rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_8_15_COMMON_BASE + DCTRL); @@ -1250,6 +1378,7 @@ static int rz_dmac_probe(struct platform_device *pdev) engine->device_tx_status =3D rz_dmac_tx_status; engine->device_prep_slave_sg =3D rz_dmac_prep_slave_sg; engine->device_prep_dma_memcpy =3D rz_dmac_prep_dma_memcpy; + engine->device_prep_dma_cyclic =3D rz_dmac_prep_dma_cyclic; engine->device_config =3D rz_dmac_config; engine->device_terminate_all =3D rz_dmac_terminate_all; engine->device_issue_pending =3D rz_dmac_issue_pending; --=20 2.43.0 From nobody Mon Feb 9 10:54:16 2026 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (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 4597A33120D for ; Mon, 26 Jan 2026 10:32:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423535; cv=none; b=sXaZrbJHPTdnSAgs7tXffyIc0Ak5Qp1dfH6RAeYHmd89FPeRKpmyFcgWJwwWOqsdfCIJe/cFD65fl52jyjQ6oE+zxZNg+4vG+h585XH94kLleSxWbeVcsSEol+pGr68L1a27fVlOF1xiQE9TwIrsp1EdyaPOCOFucJfM6eqo5MU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423535; c=relaxed/simple; bh=mZe19bFK/S4/K+saPikdJBeJIpbKrPgWGTChE+D5OPc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bGEU1i8z5z+qaafwLz8wUMP8nSzOorPiJq+KlJdowGpl3UqcKEhyA+8YnGxLCFH6rWYosEIV5VFCVwFUJS3xLwejj98R0+BtY0XuCfxpDXmCCuBkDJ170MmKnuZ/PlZ9VyvkPSfRsB6UfeeDlGmaCE8ugm8xok0RYXsOrTtX3m8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev; spf=pass smtp.mailfrom=tuxon.dev; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b=MjQRkvpG; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b="MjQRkvpG" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-4801c1ad878so48034975e9.1 for ; Mon, 26 Jan 2026 02:32:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1769423531; x=1770028331; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=77QZXmKdSVMSMO6XhwWHW9cRB7VDPOEmlJRMnWPda5M=; b=MjQRkvpGUheDT9YszmXnNK5TstIhbsMPaCX3WkJhTvkosKI9gdLXrmfia8TrjcfWHp mXIx2r2c7pfZQq2K3rE88WuDLglWzUJYl4b8S0edSADrD4OBHb5CnrlzVrcGHD5NVxcn c3ls7BDKXB4zvQALJgbxGlAOsFnRTuwYTsR4mEfW1CgP/LoWfWu8Z+iAUYjT+76D6Clz CZ8GQ1iTXfqdVjBCdb/0rcNCjhSq3EuslFsJLbIWKtB1JzL/pRdJRKOINhfHX0E69hEO YWtXcGS7zEsuJwhmgw/3jfDr1EcNo6StTOk9DwT6NN2mhJsADtoxqRj07pRBIMt2Xsq5 6nLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769423531; x=1770028331; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=77QZXmKdSVMSMO6XhwWHW9cRB7VDPOEmlJRMnWPda5M=; b=Gm5/4zgUODdQDlr/RuSK7jtErw78SPC/TQAr5ttTIC3iHGcEgMnuHvEUWStjhc5NCS HqMhiwn2iGE8LudaH9Rgcz+Rx9WSvjAITgoLzzpp5u2zTcEHH5Wu+zAgHcsOz4El2wXe buB/qdlRAa9/WYopCJHAQ86HWrifx8C88qw+jbmazosBIuBZsQy/4MEy5PyfJiuLWaY+ SQ76jlkXKB4Rdi1RQkHNOoWuBY8hp7fnaOSfR6BYu5tMjdbo4NI60LMfc29RfOdA3xYi XhJrW+UZSI7xkqVXVcN2glqkTr1KtXxbDn0g3VkX7lnm00QtYv4RoB2hvBgopTgth/Hh UNLQ== X-Forwarded-Encrypted: i=1; AJvYcCU2EuEbsjThewK4gfMYOq/THsRBEFZwkNGy3DIVn5YNHa+jtkgTlOl5mTIR30sSGjVgFY0oUcKyCLWedQ8=@vger.kernel.org X-Gm-Message-State: AOJu0YxHLp/sQjQgwXMxZdG9wT/Oc4+q5D1tSb57slI1Xex+UKAHj0cX 14sGTymrRPEvsZz1jwkjtd1/nrRoV+cSK10Xw1enBfRd4mJ/7d6oVoBSjsg9kAmktsU= X-Gm-Gg: AZuq6aJPbZxkmLVUtFFUM8KfGTzjwxPdjSJnh9tjcSC3nStUkKk6bJ01zWK9qeT7d6W jK5l4Mp3VSJZWPtNlL35zSwpPi9CV8+8hWGF/ShfGDlWW9dWv1+f1Mh8zHfXVjgs8HjfEa4KF18 /pPRZWXs0N/6L01BglnZ49SiPYZ7WxwD2F/+6d3mvYYVi3D9wHlLmgRrUPXUtLoy+YptS6p1A4E q56HS6SdPWFIIP3yzi7pAx7NdsRoQZX0QH77UTegE0IDlMJMgYmAd1f6JQQ1DhkFQc1SHNf4PdA Rjo2VoaHJi0GH2hK4DUtYWeC/WODtw4qxLiHLplD0wOEMogbkuCirr2wJ1ko2pun8aBelRvhi2q ta/PAngb/lCs306wybFOZgDZSGau2vpMb1TCE2bbKzPCuI0OYpRHyPmVCyAVQt+WY9z4qtAa6Q6 PO58PevpB+QhdtYLFDS4yjXey+V/n4+qO8A/+VOX0= X-Received: by 2002:a05:600c:4f8a:b0:477:76bf:e1fb with SMTP id 5b1f17b1804b1-4805ce4e7e2mr71803555e9.16.1769423530663; Mon, 26 Jan 2026 02:32:10 -0800 (PST) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.31]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435b1c246ecsm29715049f8f.10.2026.01.26.02.32.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jan 2026 02:32:09 -0800 (PST) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com Cc: claudiu.beznea@tuxon.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Claudiu Beznea Subject: [PATCH 5/7] dmaengine: sh: rz-dmac: Add suspend to RAM support Date: Mon, 26 Jan 2026 12:31:53 +0200 Message-ID: <20260126103155.2644586-6-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> References: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Claudiu Beznea The Renesas RZ/G3S SoC supports a power saving mode in which power to most SoC components is turned off, including the DMA IP. Add suspend to RAM support to save and restore the DMA IP registers. Cyclic DMA channels require special handling. Since they can be paused and resumed during system suspend and resume, the driver restores additional registers for these channels during the resume phase. If a channel was not explicitly paused during suspend, the driver ensures that it is paused and resumed as part of the system suspend/resume flow. This might be the case of a serial device being used with no_console_suspend. For non-cyclic channels, the dev_pm_ops::prepare callback waits for all ongoing transfers to complete before allowing suspend-to-RAM to proceed. Signed-off-by: Claudiu Beznea --- drivers/dma/sh/rz-dmac.c | 183 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 175 insertions(+), 8 deletions(-) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index ab5f49a0b9f2..8f3e2719e639 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -69,11 +69,15 @@ struct rz_dmac_desc { * enum rz_dmac_chan_status: RZ DMAC channel status * @RZ_DMAC_CHAN_STATUS_ENABLED: Channel is enabled * @RZ_DMAC_CHAN_STATUS_PAUSED: Channel is paused though DMA engine callba= cks + * @RZ_DMAC_CHAN_STATUS_PAUSED_INTERNAL: Channel is paused through driver = internal logic + * @RZ_DMAC_CHAN_STATUS_SYS_SUSPENDED: Channel was prepared for system sus= pend * @RZ_DMAC_CHAN_STATUS_CYCLIC: Channel is cyclic */ enum rz_dmac_chan_status { RZ_DMAC_CHAN_STATUS_ENABLED, RZ_DMAC_CHAN_STATUS_PAUSED, + RZ_DMAC_CHAN_STATUS_PAUSED_INTERNAL, + RZ_DMAC_CHAN_STATUS_SYS_SUSPENDED, RZ_DMAC_CHAN_STATUS_CYCLIC, }; =20 @@ -94,6 +98,10 @@ struct rz_dmac_chan { u32 chctrl; int mid_rid; =20 + struct { + u32 nxla; + } pm_state; + struct list_head ld_free; struct list_head ld_queue; struct list_head ld_active; @@ -1002,10 +1010,17 @@ static int rz_dmac_device_pause(struct dma_chan *ch= an) return rz_dmac_device_pause_set(channel, RZ_DMAC_CHAN_STATUS_PAUSED); } =20 +static int rz_dmac_device_pause_internal(struct rz_dmac_chan *channel) +{ + lockdep_assert_held(&channel->vc.lock); + + return rz_dmac_device_pause_set(channel, RZ_DMAC_CHAN_STATUS_PAUSED_INTER= NAL); +} + static int rz_dmac_device_resume_set(struct rz_dmac_chan *channel, enum rz_dmac_chan_status status) { - u32 val; + u32 val, chctrl; int ret; =20 lockdep_assert_held(&channel->vc.lock); @@ -1013,14 +1028,33 @@ static int rz_dmac_device_resume_set(struct rz_dmac= _chan *channel, if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_PAUSED))) return 0; =20 - rz_dmac_ch_writel(channel, CHCTRL_CLRSUS, CHCTRL, 1); - ret =3D read_poll_timeout_atomic(rz_dmac_ch_readl, val, - !(val & CHSTAT_SUS), 1, 1024, false, - channel, CHSTAT, 1); - if (ret) - return ret; + if (channel->status & BIT(RZ_DMAC_CHAN_STATUS_SYS_SUSPENDED)) { + /* + * We can be after a sleep state with power loss. If power was + * lost, the CHSTAT_SUS bit is zero. In this case, we need to + * enable the channel directly. Otherwise, just set the CLRSUS + * bit. + */ + val =3D rz_dmac_ch_readl(channel, CHSTAT, 1); + if (val & CHSTAT_SUS) + chctrl =3D CHCTRL_CLRSUS; + else + chctrl =3D CHCTRL_SETEN; + } else { + chctrl =3D CHCTRL_CLRSUS; + } + + rz_dmac_ch_writel(channel, chctrl, CHCTRL, 1); =20 - channel->status &=3D ~BIT(status); + if (chctrl & CHCTRL_CLRSUS) { + ret =3D read_poll_timeout_atomic(rz_dmac_ch_readl, val, + !(val & CHSTAT_SUS), 1, 1024, false, + channel, CHSTAT, 1); + if (ret) + return ret; + } + + channel->status &=3D ~(BIT(status) | BIT(RZ_DMAC_CHAN_STATUS_SYS_SUSPENDE= D)); =20 return 0; } @@ -1034,6 +1068,13 @@ static int rz_dmac_device_resume(struct dma_chan *ch= an) return rz_dmac_device_resume_set(channel, RZ_DMAC_CHAN_STATUS_PAUSED); } =20 +static int rz_dmac_device_resume_internal(struct rz_dmac_chan *channel) +{ + lockdep_assert_held(&channel->vc.lock); + + return rz_dmac_device_resume_set(channel, RZ_DMAC_CHAN_STATUS_PAUSED_INTE= RNAL); +} + /* * -----------------------------------------------------------------------= ------ * IRQ handling @@ -1438,6 +1479,131 @@ static void rz_dmac_remove(struct platform_device *= pdev) pm_runtime_disable(&pdev->dev); } =20 +static int rz_dmac_suspend_prepare(struct device *dev) +{ + struct rz_dmac *dmac =3D dev_get_drvdata(dev); + + for (unsigned int i =3D 0; i < dmac->n_channels; i++) { + struct rz_dmac_chan *channel =3D &dmac->channels[i]; + + guard(spinlock_irqsave)(&channel->vc.lock); + + /* Wait for transfer completion, except in cyclic case. */ + if (channel->status & BIT(RZ_DMAC_CHAN_STATUS_ENABLED) && + !(channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC))) + return -EAGAIN; + } + + return 0; +} + +static void rz_dmac_suspend_recover(struct rz_dmac *dmac) +{ + for (unsigned int i =3D 0; i < dmac->n_channels; i++) { + struct rz_dmac_chan *channel =3D &dmac->channels[i]; + + guard(spinlock_irqsave)(&channel->vc.lock); + + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC))) + continue; + + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_PAUSED_INTERNAL))) + continue; + + rz_dmac_device_resume_internal(channel); + } +} + +static int rz_dmac_suspend(struct device *dev) +{ + struct rz_dmac *dmac =3D dev_get_drvdata(dev); + int ret; + + for (unsigned int i =3D 0; i < dmac->n_channels; i++) { + struct rz_dmac_chan *channel =3D &dmac->channels[i]; + + guard(spinlock_irqsave)(&channel->vc.lock); + + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC))) + continue; + + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_PAUSED))) { + ret =3D rz_dmac_device_pause_internal(channel); + if (ret) { + dev_err(dev, "Failed to suspend channel %s\n", + dma_chan_name(&channel->vc.chan)); + continue; + } + } + + channel->pm_state.nxla =3D rz_dmac_ch_readl(channel, NXLA, 1); + channel->status |=3D BIT(RZ_DMAC_CHAN_STATUS_SYS_SUSPENDED); + } + + pm_runtime_put_sync(dmac->dev); + + ret =3D reset_control_assert(dmac->rstc); + if (ret) { + pm_runtime_resume_and_get(dmac->dev); + rz_dmac_suspend_recover(dmac); + } + + return ret; +} + +static int rz_dmac_resume(struct device *dev) +{ + struct rz_dmac *dmac =3D dev_get_drvdata(dev); + int ret; + + ret =3D reset_control_deassert(dmac->rstc); + if (ret) + return ret; + + ret =3D pm_runtime_resume_and_get(dmac->dev); + if (ret) { + reset_control_assert(dmac->rstc); + return ret; + } + + rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_0_7_COMMON_BASE + DCTRL); + rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_8_15_COMMON_BASE + DCTRL); + + for (unsigned int i =3D 0; i < dmac->n_channels; i++) { + struct rz_dmac_chan *channel =3D &dmac->channels[i]; + + guard(spinlock_irqsave)(&channel->vc.lock); + + rz_dmac_set_dma_req_no(dmac, channel->index, channel->mid_rid); + + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC))) { + rz_dmac_ch_writel(&dmac->channels[i], CHCTRL_DEFAULT, CHCTRL, 1); + continue; + } + + rz_dmac_ch_writel(channel, channel->pm_state.nxla, NXLA, 1); + rz_dmac_ch_writel(channel, channel->chcfg, CHCFG, 1); + rz_dmac_ch_writel(channel, CHCTRL_SWRST, CHCTRL, 1); + rz_dmac_ch_writel(channel, channel->chctrl, CHCTRL, 1); + + if (channel->status & BIT(RZ_DMAC_CHAN_STATUS_PAUSED_INTERNAL)) { + ret =3D rz_dmac_device_resume_internal(channel); + if (ret) { + dev_err(dev, "Failed to resume channel %s\n", + dma_chan_name(&channel->vc.chan)); + continue; + } + } + } + + return 0; +} + +static const struct dev_pm_ops rz_dmac_pm_ops =3D { + .prepare =3D rz_dmac_suspend_prepare, + SYSTEM_SLEEP_PM_OPS(rz_dmac_suspend, rz_dmac_resume) +}; + static const struct rz_dmac_info rz_dmac_v2h_info =3D { .icu_register_dma_req =3D rzv2h_icu_register_dma_req, .default_dma_req_no =3D RZV2H_ICU_DMAC_REQ_NO_DEFAULT, @@ -1464,6 +1630,7 @@ static struct platform_driver rz_dmac_driver =3D { .driver =3D { .name =3D "rz-dmac", .of_match_table =3D of_rz_dmac_match, + .pm =3D pm_sleep_ptr(&rz_dmac_pm_ops), }, .probe =3D rz_dmac_probe, .remove =3D rz_dmac_remove, --=20 2.43.0 From nobody Mon Feb 9 10:54:16 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (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 1ADBA331A5E for ; Mon, 26 Jan 2026 10:32:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423537; cv=none; b=IN7oz+ato6ubFXLM2hq3Bo2XwRJ9PpJaXPCpnPUFljVIw3hvZ5IzjB51ziHpi+q8pJK8pieL8C9aklZ0ZKFcv+K88HwR/34E4jM3IZVcLxaPJ6a3NZTcL1fUQvuw8dKjovuZDQ7vQ+lMHrqYiRqSiQS8uwUolfrABkM6hfQ3SK8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423537; c=relaxed/simple; bh=/CxE8jUKzLebQaXVhz58X+uWWo9J9kVtaOvO06Vm32Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YVh+lkbFKqj3NQmmnrFWIacVJrXxKROajo/SOZwQGMfLcBeAveLRabOrqnsMO5jy6BotIOcceF1nLPs/VvwGrlbBwIBvzSB24hMMdMnXO0/bGAy6zZ6dHit2zgH0Ztt4c5AVjNNhanB2IbTDKXPhpXeftbAsn0+t2Mvs9FrjOHY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev; spf=pass smtp.mailfrom=tuxon.dev; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b=oEYv7JU+; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b="oEYv7JU+" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-4801c731d0aso33987015e9.1 for ; Mon, 26 Jan 2026 02:32:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1769423532; x=1770028332; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+M5P+3SPmuUnRvbdXyjEmPFP58yjqtAcvMTbATpIr9E=; b=oEYv7JU+kWaZKo/HyvDDC8mcvHQHpiBhw0+nekONrYfKFTcBxnr7yipzvFPKdSD/P5 WSp9Pi3F7M1s/h7m928ku6TPUtF/nGnHXfX93PAcHnnc010lxft5ZB9gkomi/x4QlQYg oaRrR63w2aoaQjtxmiRGyNn6Xv3CZDBI0nexInK+RseJFaXJUnLYHjYS9choJqt1CN/v wZEooPDdcN/BH5roEubZ4SnW1Ch09auDiXD2v9Cc+znKnu0R/Mi6w8fCIX0dcmmjlLI4 qz6Bvig68Ys106xGn+1TJHWBfqq5GibxTR8me/wAn55UHDk1E18M1vzVIcf9Gh07l4+6 48/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769423532; x=1770028332; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=+M5P+3SPmuUnRvbdXyjEmPFP58yjqtAcvMTbATpIr9E=; b=AN1oBiYq0DYYWwJQgBEjdKIqBwNh55dt23Bf3AFZHliNCK38UPjFRFGZC3uGNmMLn1 jTUBnhqs+AeNAd6RW2E2wMlo9ToqGqTCoZF4qKBEF2JcC6N+LSKoHjiKRkVCSstFVuf/ m/GIL9iG+UgY30aPZqrobaqfokULPNXw3QDuto40JxM2i8IPuYeRE/CSR+zDMdgpVVPE xWGRJhDkxjtUAgYdjGmq51naPLVwc6KlfMyHdmKdFaRKf3UKD/Ko5pyYNvcjBnapB8y8 NRRsliJm0gaw6EMfuYEuXfoNHUqPiz/q852oKcpXu9XbdN6cWlSLhTz9YZDJlGIOk/1x QBzw== X-Forwarded-Encrypted: i=1; AJvYcCUMfhugKxigErkNTfDItvLef35rkeabz7c91RE0ifHuvCyT0yYTcMa8W6AgUba6qPT0sYobxGRy53Q5/8E=@vger.kernel.org X-Gm-Message-State: AOJu0YxelGNHMhOcBsonbCgX3YrunjU+uqgAa0P9l71AqTRiI0lwt76A DvzHKeyj85BUqtcbi0uYDmo4j+8xL72gQRpoOp24iK3ddnHCzuQ/EHsi0vG6fDYHrMg= X-Gm-Gg: AZuq6aLxdbypiut5k+2WFm69ELfPDPMu2rZpQAsaPAj+5pN2BYticopGqh88BBbkEZT AgcMs/7fZJz+tLqKUxwN5UrQrlp1gHChizYhhiB6wEfe8tsc5sNg5luAPteYei7F6P6JRHsfYyc 44E5sutzqN0FSKdYoHL1F2TvHbUzFEGJa2b48NVo/LOmZE+zhcNgz/+rl782dC00LMzyLtylWYw 91E3tpKSjhoj35gJUqPLmzHMz3ctO10S3yjSSQHACoV4cTBNOXKeSTq78kzokNEW1/s1Wk0rlY3 zyvyJ19FbIl63NC/Ofv9HHh8vYA6n2KTeRGAkqqR8OpMY3Ve/IUnMOeoT4XkvfshHsVAsiqkNsS jcF7qQ5pa2obKhIcSoTIzLPZHj6ak0ke+Jjtkaz9JLNWytAaHBr+QZAWZ6rwgeGrb7qvaue4lT+ xstowszjvQmgQDZGDU4QROH0YeztTcA4uKTJhs/EI= X-Received: by 2002:a5d:5d0a:0:b0:42f:bb08:d1ef with SMTP id ffacd0b85a97d-435ca145771mr6369076f8f.17.1769423532322; Mon, 26 Jan 2026 02:32:12 -0800 (PST) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.31]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435b1c246ecsm29715049f8f.10.2026.01.26.02.32.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jan 2026 02:32:11 -0800 (PST) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com Cc: claudiu.beznea@tuxon.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Claudiu Beznea Subject: [PATCH 6/7] ASoC: renesas: rz-ssi: Use generic PCM dmaengine APIs Date: Mon, 26 Jan 2026 12:31:54 +0200 Message-ID: <20260126103155.2644586-7-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> References: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Claudiu Beznea On Renesas RZ/G2L and RZ/G3S SoCs (where this was tested), captured audio files occasionally contained random spikes when viewed with a profiling tool such as Audacity. These spikes were also audible as popping noises. Using cyclic DMA resolves this issue. The driver was reworked to use the existing support provided by the generic PCM dmaengine APIs. In addition to eliminating the random spikes, the following issues were addressed: - blank periods at the beginning of recorded files, which occurred intermittently, are no longer present - no overruns or underruns were observed when continuously recording short audio files (e.g. 5 seconds) in a loop - concurrency issues in the SSI driver when enqueuing DMA requests were eliminated; previously, DMA requests could be prepared and submitted both from the DMA completion callback and the interrupt handler, which led to crashes after several hours of testing - the SSI driver logic is simplified - the number of generated interrupts is reduced by approximately 250% In the SSI platform driver probe function, the following changes were made: - the driver-specific DMA configuration was removed in favor of the generic PCM dmaengine APIs. As a result, explicit cleanup goto labels are no longer required and the driver remove callback was dropped, since resource management is now handled via devres helpers - special handling was added for IP variants operating in half-duplex mode, where the DMA channel name in the device tree is "rt"; this DMA channel name is taken into account and passed to the generic PCM dmaengine configuration data All code previously responsible for preparing and completing DMA transfers was removed, as this functionality is now handled entirely by the generic PCM dmaengine APIs. Since DMA channels must be paused and resumed during recovery paths (overruns and underruns), the DMA channel references are stored in rz_ssi_hw_params(). The logic in rz_ssi_is_dma_enabled() was updated to reflect that the driver no longer manages DMA transfers directly. Finally, rz_ssi_stream_is_play() was removed, as it had only a single remaining user after this rework, and its logic was inlined at the call site. Signed-off-by: Claudiu Beznea --- sound/soc/renesas/rz-ssi.c | 355 ++++++++----------------------------- 1 file changed, 77 insertions(+), 278 deletions(-) diff --git a/sound/soc/renesas/rz-ssi.c b/sound/soc/renesas/rz-ssi.c index 39aa865bdca3..d9c88a1975b8 100644 --- a/sound/soc/renesas/rz-ssi.c +++ b/sound/soc/renesas/rz-ssi.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include =20 @@ -87,8 +89,6 @@ struct rz_ssi_stream { struct rz_ssi_priv *priv; struct snd_pcm_substream *substream; int fifo_sample_size; /* sample capacity of SSI FIFO */ - int dma_buffer_pos; /* The address for the next DMA descriptor */ - int completed_dma_buf_pos; /* The address of the last completed DMA descr= iptor. */ int period_counter; /* for keeping track of periods transferred */ int buffer_pos; /* current frame position in the buffer */ int running; /* 0=3Dstopped, 1=3Drunning */ @@ -96,8 +96,6 @@ struct rz_ssi_stream { int uerr_num; int oerr_num; =20 - struct dma_chan *dma_ch; - int (*transfer)(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm); }; =20 @@ -108,7 +106,6 @@ struct rz_ssi_priv { struct clk *sfr_clk; struct clk *clk; =20 - phys_addr_t phys; int irq_int; int irq_tx; int irq_rx; @@ -148,9 +145,10 @@ struct rz_ssi_priv { unsigned int sample_width; unsigned int sample_bits; } hw_params_cache; -}; =20 -static void rz_ssi_dma_complete(void *data); + struct snd_dmaengine_dai_dma_data dma_dais[SNDRV_PCM_STREAM_LAST + 1]; + struct dma_chan *dmas[SNDRV_PCM_STREAM_LAST + 1]; +}; =20 static void rz_ssi_reg_writel(struct rz_ssi_priv *priv, uint reg, u32 data) { @@ -172,11 +170,6 @@ static void rz_ssi_reg_mask_setl(struct rz_ssi_priv *p= riv, uint reg, writel(val, (priv->base + reg)); } =20 -static inline bool rz_ssi_stream_is_play(struct snd_pcm_substream *substre= am) -{ - return substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK; -} - static inline struct rz_ssi_stream * rz_ssi_stream_get(struct rz_ssi_priv *ssi, struct snd_pcm_substream *subst= ream) { @@ -185,7 +178,7 @@ rz_ssi_stream_get(struct rz_ssi_priv *ssi, struct snd_p= cm_substream *substream) =20 static inline bool rz_ssi_is_dma_enabled(struct rz_ssi_priv *ssi) { - return (ssi->playback.dma_ch && (ssi->dma_rt || ssi->capture.dma_ch)); + return !ssi->playback.transfer && !ssi->capture.transfer; } =20 static void rz_ssi_set_substream(struct rz_ssi_stream *strm, @@ -215,8 +208,6 @@ static void rz_ssi_stream_init(struct rz_ssi_stream *st= rm, struct snd_pcm_substream *substream) { rz_ssi_set_substream(strm, substream); - strm->dma_buffer_pos =3D 0; - strm->completed_dma_buf_pos =3D 0; strm->period_counter =3D 0; strm->buffer_pos =3D 0; =20 @@ -242,12 +233,13 @@ static void rz_ssi_stream_quit(struct rz_ssi_priv *ss= i, dev_info(dev, "underrun =3D %d\n", strm->uerr_num); } =20 -static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate, - unsigned int channels) +static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, struct snd_pcm_substr= eam *substream, + unsigned int rate, unsigned int channels) { static u8 ckdv[] =3D { 1, 2, 4, 8, 16, 32, 64, 128, 6, 12, 24, 48, 96 = }; unsigned int channel_bits =3D 32; /* System Word Length */ unsigned long bclk_rate =3D rate * channels * channel_bits; + struct snd_dmaengine_dai_dma_data *dma_dai; unsigned int div; unsigned int i; u32 ssicr =3D 0; @@ -290,6 +282,8 @@ static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, un= signed int rate, return -EINVAL; } =20 + dma_dai =3D &ssi->dma_dais[substream->stream]; + /* * DWL: Data Word Length =3D {16, 24, 32} bits * SWL: System Word Length =3D 32 bits @@ -298,12 +292,18 @@ static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, = unsigned int rate, switch (ssi->hw_params_cache.sample_width) { case 16: ssicr |=3D SSICR_DWL(1); + dma_dai->maxburst =3D DMA_SLAVE_BUSWIDTH_2_BYTES; + dma_dai->addr_width =3D DMA_SLAVE_BUSWIDTH_2_BYTES; break; case 24: ssicr |=3D SSICR_DWL(5) | SSICR_PDTA; + dma_dai->maxburst =3D DMA_SLAVE_BUSWIDTH_4_BYTES; + dma_dai->addr_width =3D DMA_SLAVE_BUSWIDTH_4_BYTES; break; case 32: ssicr |=3D SSICR_DWL(6); + dma_dai->maxburst =3D DMA_SLAVE_BUSWIDTH_4_BYTES; + dma_dai->addr_width =3D DMA_SLAVE_BUSWIDTH_4_BYTES; break; default: dev_err(ssi->dev, "Not support %u data width", @@ -344,7 +344,7 @@ static void rz_ssi_set_idle(struct rz_ssi_priv *ssi) =20 static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *str= m) { - bool is_play =3D rz_ssi_stream_is_play(strm->substream); + bool is_play =3D strm->substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK; bool is_full_duplex; u32 ssicr, ssifcr; =20 @@ -423,14 +423,6 @@ static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct= rz_ssi_stream *strm) /* Disable TX/RX */ rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0); =20 - /* Cancel all remaining DMA transactions */ - if (rz_ssi_is_dma_enabled(ssi)) { - if (ssi->playback.dma_ch) - dmaengine_terminate_async(ssi->playback.dma_ch); - if (ssi->capture.dma_ch) - dmaengine_terminate_async(ssi->capture.dma_ch); - } - rz_ssi_set_idle(ssi); =20 return 0; @@ -458,10 +450,6 @@ static void rz_ssi_pointer_update(struct rz_ssi_stream= *strm, int frames) snd_pcm_period_elapsed(strm->substream); strm->period_counter =3D current_period; } - - strm->completed_dma_buf_pos +=3D runtime->period_size; - if (strm->completed_dma_buf_pos >=3D runtime->buffer_size) - strm->completed_dma_buf_pos =3D 0; } =20 static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *= strm) @@ -606,12 +594,6 @@ static irqreturn_t rz_ssi_interrupt(int irq, void *dat= a) if (irq =3D=3D ssi->irq_int) { /* error or idle */ bool is_stopped =3D !!(ssisr & (SSISR_RUIRQ | SSISR_ROIRQ | SSISR_TUIRQ | SSISR_TOIRQ)); - int i, count; - - if (rz_ssi_is_dma_enabled(ssi)) - count =3D 4; - else - count =3D 1; =20 if (ssi->capture.substream && is_stopped) { if (ssisr & SSISR_RUIRQ) @@ -619,7 +601,8 @@ static irqreturn_t rz_ssi_interrupt(int irq, void *data) if (ssisr & SSISR_ROIRQ) strm_capture->oerr_num++; =20 - rz_ssi_stop(ssi, strm_capture); + if (rz_ssi_is_dma_enabled(ssi)) + dmaengine_pause(ssi->dmas[SNDRV_PCM_STREAM_CAPTURE]); } =20 if (ssi->playback.substream && is_stopped) { @@ -628,7 +611,8 @@ static irqreturn_t rz_ssi_interrupt(int irq, void *data) if (ssisr & SSISR_TOIRQ) strm_playback->oerr_num++; =20 - rz_ssi_stop(ssi, strm_playback); + if (rz_ssi_is_dma_enabled(ssi)) + dmaengine_pause(ssi->dmas[SNDRV_PCM_STREAM_PLAYBACK]); } =20 /* Clear all flags */ @@ -637,12 +621,16 @@ static irqreturn_t rz_ssi_interrupt(int irq, void *da= ta) =20 /* Add/remove more data */ if (ssi->capture.substream && is_stopped) { - for (i =3D 0; i < count; i++) + if (rz_ssi_is_dma_enabled(ssi)) + dmaengine_resume(ssi->dmas[SNDRV_PCM_STREAM_CAPTURE]); + else strm_capture->transfer(ssi, strm_capture); } =20 if (ssi->playback.substream && is_stopped) { - for (i =3D 0; i < count; i++) + if (rz_ssi_is_dma_enabled(ssi)) + dmaengine_resume(ssi->dmas[SNDRV_PCM_STREAM_PLAYBACK]); + else strm_playback->transfer(ssi, strm_playback); } =20 @@ -679,153 +667,11 @@ static irqreturn_t rz_ssi_interrupt(int irq, void *d= ata) return IRQ_HANDLED; } =20 -static int rz_ssi_dma_slave_config(struct rz_ssi_priv *ssi, - struct dma_chan *dma_ch, bool is_play) -{ - struct dma_slave_config cfg; - - memset(&cfg, 0, sizeof(cfg)); - - cfg.direction =3D is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; - cfg.dst_addr =3D ssi->phys + SSIFTDR; - cfg.src_addr =3D ssi->phys + SSIFRDR; - if (ssi->hw_params_cache.sample_width =3D=3D 16) { - cfg.src_addr_width =3D DMA_SLAVE_BUSWIDTH_2_BYTES; - cfg.dst_addr_width =3D DMA_SLAVE_BUSWIDTH_2_BYTES; - } else { - cfg.src_addr_width =3D DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width =3D DMA_SLAVE_BUSWIDTH_4_BYTES; - } - - return dmaengine_slave_config(dma_ch, &cfg); -} - -static int rz_ssi_dma_transfer(struct rz_ssi_priv *ssi, - struct rz_ssi_stream *strm) -{ - struct snd_pcm_substream *substream =3D strm->substream; - struct dma_async_tx_descriptor *desc; - struct snd_pcm_runtime *runtime; - enum dma_transfer_direction dir; - u32 dma_paddr, dma_size; - int amount; - - if (!rz_ssi_stream_is_valid(ssi, strm)) - return -EINVAL; - - runtime =3D substream->runtime; - if (runtime->state =3D=3D SNDRV_PCM_STATE_DRAINING) - /* - * Stream is ending, so do not queue up any more DMA - * transfers otherwise we play partial sound clips - * because we can't shut off the DMA quick enough. - */ - return 0; - - dir =3D rz_ssi_stream_is_play(substream) ? DMA_MEM_TO_DEV : DMA_DEV_TO_ME= M; - - /* Always transfer 1 period */ - amount =3D runtime->period_size; - - /* DMA physical address and size */ - dma_paddr =3D runtime->dma_addr + frames_to_bytes(runtime, - strm->dma_buffer_pos); - dma_size =3D frames_to_bytes(runtime, amount); - desc =3D dmaengine_prep_slave_single(strm->dma_ch, dma_paddr, dma_size, - dir, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { - dev_err(ssi->dev, "dmaengine_prep_slave_single() fail\n"); - return -ENOMEM; - } - - desc->callback =3D rz_ssi_dma_complete; - desc->callback_param =3D strm; - - if (dmaengine_submit(desc) < 0) { - dev_err(ssi->dev, "dmaengine_submit() fail\n"); - return -EIO; - } - - /* Update DMA pointer */ - strm->dma_buffer_pos +=3D amount; - if (strm->dma_buffer_pos >=3D runtime->buffer_size) - strm->dma_buffer_pos =3D 0; - - /* Start DMA */ - dma_async_issue_pending(strm->dma_ch); - - return 0; -} - -static void rz_ssi_dma_complete(void *data) -{ - struct rz_ssi_stream *strm =3D (struct rz_ssi_stream *)data; - - if (!strm->running || !strm->substream || !strm->substream->runtime) - return; - - /* Note that next DMA transaction has probably already started */ - rz_ssi_pointer_update(strm, strm->substream->runtime->period_size); - - /* Queue up another DMA transaction */ - rz_ssi_dma_transfer(strm->priv, strm); -} - -static void rz_ssi_release_dma_channels(struct rz_ssi_priv *ssi) -{ - if (ssi->playback.dma_ch) { - dma_release_channel(ssi->playback.dma_ch); - ssi->playback.dma_ch =3D NULL; - if (ssi->dma_rt) - ssi->dma_rt =3D false; - } - - if (ssi->capture.dma_ch) { - dma_release_channel(ssi->capture.dma_ch); - ssi->capture.dma_ch =3D NULL; - } -} - -static int rz_ssi_dma_request(struct rz_ssi_priv *ssi, struct device *dev) -{ - ssi->playback.dma_ch =3D dma_request_chan(dev, "tx"); - if (IS_ERR(ssi->playback.dma_ch)) - ssi->playback.dma_ch =3D NULL; - - ssi->capture.dma_ch =3D dma_request_chan(dev, "rx"); - if (IS_ERR(ssi->capture.dma_ch)) - ssi->capture.dma_ch =3D NULL; - - if (!ssi->playback.dma_ch && !ssi->capture.dma_ch) { - ssi->playback.dma_ch =3D dma_request_chan(dev, "rt"); - if (IS_ERR(ssi->playback.dma_ch)) { - ssi->playback.dma_ch =3D NULL; - goto no_dma; - } - - ssi->dma_rt =3D true; - } - - if (!rz_ssi_is_dma_enabled(ssi)) - goto no_dma; - - return 0; - -no_dma: - rz_ssi_release_dma_channels(ssi); - - return -ENODEV; -} - static int rz_ssi_trigger_resume(struct rz_ssi_priv *ssi, struct rz_ssi_st= ream *strm) { struct snd_pcm_substream *substream =3D strm->substream; - struct snd_pcm_runtime *runtime =3D substream->runtime; int ret; =20 - strm->dma_buffer_pos =3D strm->completed_dma_buf_pos + runtime->period_si= ze; - if (rz_ssi_is_stream_running(&ssi->playback) || rz_ssi_is_stream_running(&ssi->capture)) return 0; @@ -834,7 +680,7 @@ static int rz_ssi_trigger_resume(struct rz_ssi_priv *ss= i, struct rz_ssi_stream * if (ret) return ret; =20 - return rz_ssi_clk_setup(ssi, ssi->hw_params_cache.rate, + return rz_ssi_clk_setup(ssi, substream, ssi->hw_params_cache.rate, ssi->hw_params_cache.channels); } =20 @@ -843,7 +689,7 @@ static int rz_ssi_dai_trigger(struct snd_pcm_substream = *substream, int cmd, { struct rz_ssi_priv *ssi =3D snd_soc_dai_get_drvdata(dai); struct rz_ssi_stream *strm =3D rz_ssi_stream_get(ssi, substream); - int ret =3D 0, i, num_transfer =3D 1; + int ret =3D 0; =20 switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: @@ -857,28 +703,7 @@ static int rz_ssi_dai_trigger(struct snd_pcm_substream= *substream, int cmd, if (cmd =3D=3D SNDRV_PCM_TRIGGER_START) rz_ssi_stream_init(strm, substream); =20 - if (rz_ssi_is_dma_enabled(ssi)) { - bool is_playback =3D rz_ssi_stream_is_play(substream); - - if (ssi->dma_rt) - ret =3D rz_ssi_dma_slave_config(ssi, ssi->playback.dma_ch, - is_playback); - else - ret =3D rz_ssi_dma_slave_config(ssi, strm->dma_ch, - is_playback); - - /* Fallback to pio */ - if (ret < 0) { - ssi->playback.transfer =3D rz_ssi_pio_send; - ssi->capture.transfer =3D rz_ssi_pio_recv; - rz_ssi_release_dma_channels(ssi); - } else { - /* For DMA, queue up multiple DMA descriptors */ - num_transfer =3D 4; - } - } - - for (i =3D 0; i < num_transfer; i++) { + if (!rz_ssi_is_dma_enabled(ssi)) { ret =3D strm->transfer(ssi, strm); if (ret) return ret; @@ -1024,6 +849,9 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substre= am *substream, return -EINVAL; } =20 + /* Save the DMA channels for recovery. */ + ssi->dmas[substream->stream] =3D snd_dmaengine_pcm_get_chan(substream); + if (rz_ssi_is_stream_running(&ssi->playback) || rz_ssi_is_stream_running(&ssi->capture)) { if (rz_ssi_is_valid_hw_params(ssi, rate, channels, sample_width, sample_= bits)) @@ -1039,10 +867,21 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_subst= ream *substream, if (ret) return ret; =20 - return rz_ssi_clk_setup(ssi, rate, channels); + return rz_ssi_clk_setup(ssi, substream, rate, channels); +} + +static int rz_ssi_dai_probe(struct snd_soc_dai *dai) +{ + struct rz_ssi_priv *ssi =3D snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, &ssi->dma_dais[SNDRV_PCM_STREAM_PLAYBACK], + &ssi->dma_dais[SNDRV_PCM_STREAM_CAPTURE]); + + return 0; } =20 static const struct snd_soc_dai_ops rz_ssi_dai_ops =3D { + .probe =3D rz_ssi_dai_probe, .startup =3D rz_ssi_startup, .shutdown =3D rz_ssi_shutdown, .trigger =3D rz_ssi_dai_trigger, @@ -1054,7 +893,8 @@ static const struct snd_pcm_hardware rz_ssi_pcm_hardwa= re =3D { .info =3D SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME, + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_PAUSE, .buffer_bytes_max =3D PREALLOC_BUFFER, .period_bytes_min =3D 32, .period_bytes_max =3D 8192, @@ -1074,26 +914,6 @@ static int rz_ssi_pcm_open(struct snd_soc_component *= component, SNDRV_PCM_HW_PARAM_PERIODS); } =20 -static snd_pcm_uframes_t rz_ssi_pcm_pointer(struct snd_soc_component *comp= onent, - struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd =3D snd_soc_substream_to_rtd(substream); - struct snd_soc_dai *dai =3D snd_soc_rtd_to_cpu(rtd, 0); - struct rz_ssi_priv *ssi =3D snd_soc_dai_get_drvdata(dai); - struct rz_ssi_stream *strm =3D rz_ssi_stream_get(ssi, substream); - - return strm->buffer_pos; -} - -static int rz_ssi_pcm_new(struct snd_soc_component *component, - struct snd_soc_pcm_runtime *rtd) -{ - snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, - rtd->card->snd_card->dev, - PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); - return 0; -} - static struct snd_soc_dai_driver rz_ssi_soc_dai[] =3D { { .name =3D "rz-ssi-dai", @@ -1116,15 +936,19 @@ static struct snd_soc_dai_driver rz_ssi_soc_dai[] = =3D { static const struct snd_soc_component_driver rz_ssi_soc_component =3D { .name =3D "rz-ssi", .open =3D rz_ssi_pcm_open, - .pointer =3D rz_ssi_pcm_pointer, - .pcm_construct =3D rz_ssi_pcm_new, .legacy_dai_naming =3D 1, }; =20 +static struct snd_dmaengine_pcm_config rz_ssi_dmaegine_pcm_conf =3D { + .prepare_slave_config =3D snd_dmaengine_pcm_prepare_slave_config, +}; + static int rz_ssi_probe(struct platform_device *pdev) { + struct device_node *np =3D pdev->dev.of_node; struct device *dev =3D &pdev->dev; struct rz_ssi_priv *ssi; + unsigned int flags =3D 0; struct clk *audio_clk; struct resource *res; int ret; @@ -1138,7 +962,6 @@ static int rz_ssi_probe(struct platform_device *pdev) if (IS_ERR(ssi->base)) return PTR_ERR(ssi->base); =20 - ssi->phys =3D res->start; ssi->clk =3D devm_clk_get(dev, "ssi"); if (IS_ERR(ssi->clk)) return PTR_ERR(ssi->clk); @@ -1162,16 +985,21 @@ static int rz_ssi_probe(struct platform_device *pdev) =20 ssi->audio_mck =3D ssi->audio_clk_1 ? ssi->audio_clk_1 : ssi->audio_clk_2; =20 - /* Detect DMA support */ - ret =3D rz_ssi_dma_request(ssi, dev); - if (ret < 0) { - dev_warn(dev, "DMA not available, using PIO\n"); + ssi->dma_dais[SNDRV_PCM_STREAM_PLAYBACK].addr =3D (dma_addr_t)res->start = + SSIFTDR; + ssi->dma_dais[SNDRV_PCM_STREAM_CAPTURE].addr =3D (dma_addr_t)res->start = + SSIFRDR; + + if (of_property_match_string(np, "dma-names", "rt") =3D=3D 0) { + flags =3D SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX; + rz_ssi_dmaegine_pcm_conf.chan_names[SNDRV_PCM_STREAM_PLAYBACK] =3D "rt"; + } + + ret =3D devm_snd_dmaengine_pcm_register(&pdev->dev, &rz_ssi_dmaegine_pcm_= conf, flags); + if (ret) { + dev_warn(dev, "DMA not available, using PIO!\n"); ssi->playback.transfer =3D rz_ssi_pio_send; ssi->capture.transfer =3D rz_ssi_pio_recv; } else { - dev_info(dev, "DMA enabled"); - ssi->playback.transfer =3D rz_ssi_dma_transfer; - ssi->capture.transfer =3D rz_ssi_dma_transfer; + dev_info(dev, "DMA enabled\n"); } =20 ssi->playback.priv =3D ssi; @@ -1182,17 +1010,13 @@ static int rz_ssi_probe(struct platform_device *pde= v) =20 /* Error Interrupt */ ssi->irq_int =3D platform_get_irq_byname(pdev, "int_req"); - if (ssi->irq_int < 0) { - ret =3D ssi->irq_int; - goto err_release_dma_chs; - } + if (ssi->irq_int < 0) + return ssi->irq_int; =20 ret =3D devm_request_irq(dev, ssi->irq_int, rz_ssi_interrupt, 0, dev_name(dev), ssi); - if (ret < 0) { - dev_err_probe(dev, ret, "irq request error (int_req)\n"); - goto err_release_dma_chs; - } + if (ret < 0) + return dev_err_probe(dev, ret, "irq request error (int_req)\n"); =20 if (!rz_ssi_is_dma_enabled(ssi)) { /* Tx and Rx interrupts (pio only) */ @@ -1233,43 +1057,19 @@ static int rz_ssi_probe(struct platform_device *pde= v) } =20 ssi->rstc =3D devm_reset_control_get_exclusive(dev, NULL); - if (IS_ERR(ssi->rstc)) { - ret =3D PTR_ERR(ssi->rstc); - goto err_release_dma_chs; - } + if (IS_ERR(ssi->rstc)) + return dev_err_probe(dev, PTR_ERR(ssi->rstc), "Failed to get reset\n"); =20 /* Default 0 for power saving. Can be overridden via sysfs. */ pm_runtime_set_autosuspend_delay(dev, 0); pm_runtime_use_autosuspend(dev); ret =3D devm_pm_runtime_enable(dev); - if (ret < 0) { - dev_err(dev, "Failed to enable runtime PM!\n"); - goto err_release_dma_chs; - } - - ret =3D devm_snd_soc_register_component(dev, &rz_ssi_soc_component, - rz_ssi_soc_dai, - ARRAY_SIZE(rz_ssi_soc_dai)); - if (ret < 0) { - dev_err(dev, "failed to register snd component\n"); - goto err_release_dma_chs; - } - - return 0; - -err_release_dma_chs: - rz_ssi_release_dma_channels(ssi); - - return ret; -} - -static void rz_ssi_remove(struct platform_device *pdev) -{ - struct rz_ssi_priv *ssi =3D dev_get_drvdata(&pdev->dev); - - rz_ssi_release_dma_channels(ssi); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to enable runtime PM!\n"); =20 - reset_control_assert(ssi->rstc); + return devm_snd_soc_register_component(dev, &rz_ssi_soc_component, + rz_ssi_soc_dai, + ARRAY_SIZE(rz_ssi_soc_dai)); } =20 static const struct of_device_id rz_ssi_of_match[] =3D { @@ -1304,7 +1104,6 @@ static struct platform_driver rz_ssi_driver =3D { .pm =3D pm_ptr(&rz_ssi_pm_ops), }, .probe =3D rz_ssi_probe, - .remove =3D rz_ssi_remove, }; =20 module_platform_driver(rz_ssi_driver); --=20 2.43.0 From nobody Mon Feb 9 10:54:16 2026 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (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 AB98C331A71 for ; Mon, 26 Jan 2026 10:32:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423537; cv=none; b=Uh+fHUgUSJ9mU+00Zkhi/RgOg7Skfd9WDZjDTEPyT5JKd67UUYUO43IW5zR0hERk+6UE2W0bSDZXlPy/r0rhb5X+GmHidkV7OrKKnA7/M/IfiPeJs5lOsMdDBfAM212/LeCGQxdz+A0Jxc1VHj0/GTL/VypCw7qNuLxdsHQpp4I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769423537; c=relaxed/simple; bh=rLi08UdXsCL3zvjViBaowms6zxtQNJXRNf02+HbElyk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pePjL8eTqjoqPbUYZVdzcE+oGFyShasmATuyg+CeJkS8Ame8cLRr1l5etVje0JXnHN6NIZBZvAhUbMuFWxs6FNkSH5uPGTIn92xxf+J2MbjQ9GuFGA1MBeKd2mXMaPDv1pvFVYmQXYDiu7pBgkkGSX5OdsF1LJzCXisMQBNawDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev; spf=pass smtp.mailfrom=tuxon.dev; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b=kPQjfLTV; arc=none smtp.client-ip=209.85.221.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tuxon.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tuxon.dev header.i=@tuxon.dev header.b="kPQjfLTV" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-43246af170aso2456593f8f.0 for ; Mon, 26 Jan 2026 02:32:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1769423534; x=1770028334; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mVTiMUECZKumoxUGmttzNBifGHS5PA4+h4GwvqluTUU=; b=kPQjfLTVMBWsaLlE8cWmxYXSBVeil1Z7g5Uco6hreXEpt8zOO1NH+trhVC2EPxwToT VxRjk+OymT9ZQ7Qg/JpxwGpTLoX8BO6fS3/JODGcmWD04ZZYS7E/jevsAQFVu0zo7s6Q cv9ylzUahw85/bLx/+6VuMjTqqUO0QROVkouPhRNBW9jlxiEeZQVPOYcaWIk17rY+ySP aX8lmdeUuwmq1/0ouwJ+42YacK0qLs+R3V4KP4IiOrIx2W7BzEMeJh5lrV5hIbYPcAgT bI3CNsGBkyn7NuA+kTkqOWRbUZ1CbHtrXQT1CuCYNmI+yUzPjpcUVevDpTEAH0Oa7c3l 9UHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769423534; x=1770028334; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=mVTiMUECZKumoxUGmttzNBifGHS5PA4+h4GwvqluTUU=; b=u9QF4zzjRl97uPg9XjzY3Tnd7i48JZBnugrI4BEp7GyveFtSVnlcRXrPzJoMDE9UQ2 LMK0lfnKyKTJlB/YBVFMl7JU8YQ/Abh2rnwAbhQf94yZPrltswhIRaUbFpM53vvyuWBB G6LiZK+v5tZYO+f1gbwDXc4KCJ0LJhRpSYJSOVSS/NhT5KMy5Dv6AP2w++YV1QRvSXa2 e8BMPlEAvmgB10v/Z5iw0li7etZpB9S+plgBe+HstIlubU1kr6iGYz1u5QDNyGRE6boJ 7mIFautN1BVvHJi6ATzuhM7eZ+p9Dgnj5D+Z+yQVJunqnUDFBiVSSLPtC/jnKTfgOOTT Hrlw== X-Forwarded-Encrypted: i=1; AJvYcCXY/8YK9lYU5iV/xnXLibaCanelq+b7A1gTNRbbaHBJDUyJcJlnrnQdv/pG3v/tKVGpMp7yFutDFSuI7c0=@vger.kernel.org X-Gm-Message-State: AOJu0Yy3C34TVIrbDruU7/a5nJc+dJSi63WfITBBzqloNlH9kj88aZ4E RLGv6qNgo0ySDy0C61XU8CESVWxsSgkTn5aFj6XCkHym/QG8kmaLJConbBVZDUdwwJo= X-Gm-Gg: AZuq6aLRsF3QIh+BAobdXTobb42jFY0rnnbpMEsBK/61qk7dBvRe12YyNHekrzPCSM7 6qLYCBICfb7x/ou+q3wlVk/6rdAm0GGCXTeMP7dqJsMyLVYCPN66eXfy1TqC3/WULvAQ2DCS7Uk LXhY6h+L+gMxJ9wWXyE2iiVRTBkMqjlBhJAng0aze2otwKy4wUsUMx+96E1T0H6hDoXg2tTZWVv FzPjjds+rkK/RK53Bz5JpB7y7aI486+ek4isGxyr/p2hDTq6tXOSgBisslAw8IeUZ/zTI3KJvYx DaSlM2RqaXqNO0K12yfAPEXxqkHs6ZfmG6iGJz1SwqV1kTE++V8DcMZo0ZaUERpoYTDOFvYxE5l HCzTN5eRCcUeiynrhd5ksPeupqV4eN12iMdKEMOlWjQuRDDf5nlFpznifADqZzSolLX8KdLMori GYWY1RtyJueKQL5wB0DWsthi7CSsAeTOBTXi4xt8dbSGEYiS4EHA== X-Received: by 2002:a05:6000:2210:b0:435:bdc2:461 with SMTP id ffacd0b85a97d-435c9d18f01mr7343320f8f.21.1769423533834; Mon, 26 Jan 2026 02:32:13 -0800 (PST) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.31]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435b1c246ecsm29715049f8f.10.2026.01.26.02.32.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jan 2026 02:32:13 -0800 (PST) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com Cc: claudiu.beznea@tuxon.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Claudiu Beznea Subject: [PATCH 7/7] dmaengine: sh: rz-dmac: Set the Link End (LE) bit on the last descriptor Date: Mon, 26 Jan 2026 12:31:55 +0200 Message-ID: <20260126103155.2644586-8-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> References: <20260126103155.2644586-1-claudiu.beznea.uj@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Claudiu Beznea On an RZ/G2L-based system, it has been observed that when the DMA channels for all enabled IPs are active (TX and RX for one serial IP, TX and RX for one audio IP, and TX and RX for one SPI IP), shortly after all of them are started, the system can become irrecoverably blocked. In one debug session the system did not block, and the DMA HW registers were inspected. It was found that the DER (Descriptor Error) bit in the CHSTAT register for one of the SPI DMA channels was set. According to the RZ/G2L HW Manual, Rev. 1.30, chapter 14.4.7 Channel Status Register n/nS (CHSTAT_n/nS), description of the DER bit, the DER bit is set when the LV (Link Valid) value loaded with a descriptor in link mode is 0. This means that the DMA engine has loaded an invalid descriptor (as defined in Table 14.14, Header Area, of the same manual). The same chapter states that when a descriptor error occurs, the transfer is stopped, but no DMA error interrupt is generated. Set the LE bit on the last descriptor of a transfer. This informs the DMA engine that this is the final descriptor for the transfer. Signed-off-by: Claudiu Beznea --- drivers/dma/sh/rz-dmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index 8f3e2719e639..3a77a560fcd5 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -206,6 +206,7 @@ struct rz_dmac { =20 /* LINK MODE DESCRIPTOR */ #define HEADER_LV BIT(0) +#define HEADER_LE BIT(1) #define HEADER_WBD BIT(2) =20 #define RZ_DMAC_MAX_CHAN_DESCRIPTORS 16 @@ -383,7 +384,7 @@ static void rz_dmac_prepare_desc_for_memcpy(struct rz_d= mac_chan *channel) lmdesc->chcfg =3D chcfg; lmdesc->chitvl =3D 0; lmdesc->chext =3D 0; - lmdesc->header =3D HEADER_LV; + lmdesc->header =3D HEADER_LV | HEADER_LE; =20 rz_dmac_set_dma_req_no(dmac, channel->index, dmac->info->default_dma_req_= no); =20 @@ -425,7 +426,7 @@ static void rz_dmac_prepare_descs_for_slave_sg(struct r= z_dmac_chan *channel) lmdesc->chext =3D 0; if (i =3D=3D (sg_len - 1)) { lmdesc->chcfg =3D (channel->chcfg & ~CHCFG_DEM); - lmdesc->header =3D HEADER_LV; + lmdesc->header =3D HEADER_LV | HEADER_LE; } else { lmdesc->chcfg =3D channel->chcfg; lmdesc->header =3D HEADER_LV; --=20 2.43.0