From nobody Fri Apr 3 08:22:42 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (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 8491439BFF5 for ; Fri, 20 Mar 2026 11:28:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006127; cv=none; b=DUq/Ybq6MYojkcek8xYTcb/3TSOBnA8Reem7mC/CjBn0QAmKmMi2gSnxNI+RyCC6a1GZymxwwhDg9gjtp4EC+mlSLQhxKhJJqM5/B9rlyoLie99ny85bRmN3dz6vQelfTfeA3y/R5mci0yLblm0AJtMb2Hgpg+XOxXnFNzWjlM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006127; c=relaxed/simple; bh=wmr9euWcjMPiYL6aerS6JNLwSHajZ0RgtQYB1/Fq66c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mVoTSrsjvmMrXi7jGZiuFFFXNpM6TORU8eQcOLvxpezyEgogBoNf0Ujf+5vJCeJrVAmEPJ5wgGOPD68nAud8mTP+M+d+TzIFi4O/KdnlYIFESX1hwjvXvCjT3XXffLStjFoqLt8vLwk9EP5mA+edwrSRfm2KZCGnVnbnWN+zeto= 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=SNRAD1nE; arc=none smtp.client-ip=209.85.128.54 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="SNRAD1nE" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-4852a9c6309so4197155e9.0 for ; Fri, 20 Mar 2026 04:28:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1774006124; x=1774610924; 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=veJgc6lsn6LoKy5z2ASTYaikRHENJLTUNe/jR8sCCz4=; b=SNRAD1nESNOnFbZTYx1zxjVbP6a4GEnhqWuftV77S/AIccGF1vGf/8g1b/LOQlhEqX lUuMU3+OMOWhhCVhMVtC/gC/0aKkg+5VHaQdQDRVYuiVNWi9MFlGHPvYyGVjZ5CpvIMC pdmDsEVzEXM8wXkbHe3XcoIfNPdDns0xBIG27NqEVKjdGP+wV1KM5oAr1yWGdHRKkO0h hKZQxGXb/TgWXBhnYTL66ZElWYoc6n0vkDXHRRDGo/WfHTtZ0x9S1pH6Kw7PY/yKE+Hc 48NT8AKc50A86MpV0at0CN5q5ojZa4FnjeEEjd8gENPFFTyAWVhM/avrx7EOOvAT52UU au/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774006124; x=1774610924; 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=veJgc6lsn6LoKy5z2ASTYaikRHENJLTUNe/jR8sCCz4=; b=e7nWerjw64fahkBxb0dMz9tYD9dgJ8HUIeO4FMidy2Gse6plytKxNPWFnO7e8qTzCM N3Ny9e0PdIPjlyb1T4TlonsM1yN9DE7n7Skv00MzWW32A2hWCu/9Mw6aUpxolDsDaQKa YfUw4T8euHOfbyLKo8wZNjNoG/btVIhyiwc9Eq+3yZlnK39EwyECJrYcIAR3nWo5PJxN nb0oewaTuvIjhqtc3pkAaazDLswi26pmxsOrb816fED3YfE75P2tG5eox4m6SRdyCkOZ f/WFusxLh1TbWp6u7DBPppOaLBmqygs2Wrv0/gZ5x/zqwJvJd2KMJU+FzO/2iWmkMYOo XL8w== X-Forwarded-Encrypted: i=1; AJvYcCU7m1keJbW48P+xP4v/ihDsYKhMQDsHsWDpqQ7m559ZDZmobGt0W/43ZUMe2DmElAFg016gx9PFdUoMUp4=@vger.kernel.org X-Gm-Message-State: AOJu0YwiGuJzL09aiShLBh9TqA/A4BzA/++8zPV3ielDundm9fALNOiq w8/SNIH7DbJWJdEXLSiqqaYv11g/FtB2X0XBtccd2O78NYbz4dkwwDiyalIPTK2hFYI= X-Gm-Gg: ATEYQzw/pnmOHuxItygLj6XoOEwsIMW4XotlPTLU1AUHIuwblp5UKCJQdNJ33ab1/qu +MHz51Svu8ityjTgwzi0zu+9qQIzV639G+L0DOmHFVbbf/z7D0E3k3oAMxzHCMGT0/EDPO7DXWp 6ClMtzAwXDu6x5QNPdowiexlpSyMxS8GPn+BeYvG0Rd58844xku7mnXIuZa0xz/hu0lJEgKCYfW 1ly+MtlNTlCwUn983jbLEX4J4zfH8j6HEPhgM5G037D+/Uf+WHtgFRGwoNq6CelO+yyZzf6Jrh4 BEoJAx1JfckDKEcMb0Aj5DTewrqDQABnCw0CzzTvMYwl30K3BLlIOiBmhJ8Jf0oTK/E/ojIStS4 5bEieKNN/JOoN77HjHCk3Lehg0uqovo8qBFALys6RO8sv9BZzvq3d1c4JHK5WPFjVxl5ZGFgd25 LOIMEmeiAL/eBpqZgBMkTK+SPQ0F23C/fkAt+GIXjkPe9kUohBe9mVRQjtyy2FfQs= X-Received: by 2002:a05:600c:4fc8:b0:486:fbf6:abd4 with SMTP id 5b1f17b1804b1-486fedbf2d4mr40608545e9.9.1774006123656; Fri, 20 Mar 2026 04:28:43 -0700 (PDT) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.216]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-486fe836784sm49869935e9.13.2026.03.20.04.28.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2026 04:28:43 -0700 (PDT) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, Frank.Li@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com, john.madieu.xa@bp.renesas.com, kuninori.morimoto.gx@renesas.com, tommaso.merciai.xr@bp.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 v2 1/7] dmaengine: sh: rz-dmac: Add enable status bit Date: Fri, 20 Mar 2026 13:28:32 +0200 Message-ID: <20260320112838.2200198-2-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260320112838.2200198-1-claudiu.beznea.uj@bp.renesas.com> References: <20260320112838.2200198-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 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 --- Changes in v2: - fixed typo in patch description 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 625ff29024de..8148a1c78e12 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; @@ -295,6 +305,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 @@ -306,6 +318,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) @@ -571,6 +585,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 @@ -833,8 +850,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); @@ -874,8 +890,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 Fri Apr 3 08:22:42 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (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 8CB683A782A for ; Fri, 20 Mar 2026 11:28:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006129; cv=none; b=tfrNSllHbESCEbRz3DzwjXDxT18j0Z5ED74f12gziKCNYj9zuzUunJdQ9qmPxY3BXMUTZUN4ig4LVQx/aBQ74rnN4kl473Rs5X6/MAwKDmH9jpFYn/W8sd4nG5T7baAV0guXflVYw4Hqf3FttTGUM3ufPSMno0zXMypElSOosKM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006129; c=relaxed/simple; bh=JdUzXmpCIZw4oaJUcFexv5JNulg2ymIkM6cKTdwhWCc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RZe0Qe/omWZ7Iyk6goxYEuqRnD5mp4lh87sJ6EGNWJCT4qqDBfFuf0jeoI8Ul9dhOvq8vd0DJ2LYQ2EfFZOonIHL5s9OIkfhFb1Z1KiNCmri681cCPz3TIbvF4lVwAcVvweKqtqG/1VM1L0udnSec9qqtX4cjVlQGFG0g0igfQs= 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=Qb9z1Mz7; arc=none smtp.client-ip=209.85.128.53 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="Qb9z1Mz7" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-48374014a77so17258675e9.3 for ; Fri, 20 Mar 2026 04:28:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1774006126; x=1774610926; 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=KFFm2+JqQAqu98CO2w98M9b7NER9zgq+RoPb1v33LV4=; b=Qb9z1Mz7Z1UTkOTrQoYqmRU4HAAQI6cBP1ssJiFfjp0RS0WdSqpsUf48GDvNVvx6Dj uC8gXe2yTaMnkgDzWcTnrrJAjcm52pYjdYdMsRZ9ybO/VIqFlKvP+8zjKSrXjR4XLhW+ rc9pHA+snxrDYeR7xicOZtq9zkA9vXPEdo9dUQFjEyHpGmf3DZZFUGwP04bKxkk+PR+A WiblYFDC6RSfQrV+96NtQCszoOw5qZaDU7wT65kE1xvqZ2+3tmrGvr2pKrEPNIP/Dm2k 09A2oYHPFvfZeFTjWpskiklRJshBZORmGkCLv/h4PxBnusx2PM/Q2WJ9gLhU602MTQb1 gIwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774006126; x=1774610926; 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=KFFm2+JqQAqu98CO2w98M9b7NER9zgq+RoPb1v33LV4=; b=IXk8LXFoJCwycnbCnrTMBLgfpxwtmY8wJul2oCb00bkgg8I4YVM82stKVhn3+W3fkQ CYsAT3r5ryOBVBgDw2FGiKXNGfkZhjGQbl79oVd2Izf66hTLaMY3QQcsnbVeYVBv9dYa jHq7FB3udzdXRQaEwaSEHZODmeRquPBRUZj16sLK6moVjm8CzperrcxE+Nc+Gms6/6Qk v4pZYbHwe+PyFwshgHvIhmzUKwQOzHkxfOOsQ1xdX9A5tG4kybx9PporKD4R1T60IFdz I/CsDd86SDCn084cqmCN6Lo/1UhcmuU90ne3Uk0Slqd0j2Aq4L87Jdkdv1LF7R7ht+KA pbig== X-Forwarded-Encrypted: i=1; AJvYcCV8RZil8Q3QnLdWFnebFnZRxVoQtIzf86xRqqgz7UYVuz1ilIwZW3byifBaOBjkGvCIs2L5ARm6hxGRELA=@vger.kernel.org X-Gm-Message-State: AOJu0YwT79MTjUlTcVV4uP7WhXkW/Ipi6qSmVFbiVnqT6JTNCfFPckve qDtx4i9u/HsD0DoGkyhSJVaYu0T0KEVj3+g2tR7/MBfQgAsOxSJ2ujRTs1gOt5sIaY4= X-Gm-Gg: ATEYQzx/gzXlg90Fq5CQjckKfXYaNFM+lu+BIUxUX1ahZvXAH5dKcUNcaiT1eGGOkun p/29AL/5J7Zn93WEAjlRH+gL2UwPZ86B8c1NV6vhsxsiaxLpxW0eeEvdvJIg1SIvEGkLw4lJwxW YjalDDREolfcuNh7l94YTrrpKeSxF2SLXbFcD0/95dc548TZPSjAYcnjDpXhq089K6gDwtMhkjZ gBBwRVKvTVI4tQjIcyBKnS+FOuu/G6nzXdddRfEzxDgloz4Dq2weH0SQtsTo/B2z4mdlmemfF/T aLJOMZnQf5s3pVuw/jmAtCEFM7rHcwnFrDGcSrKRF8R5b6mP7P/qIv0LOdn4QtBxtG0HW3pvtr5 8G65dOf3icKOBPPh5PVt13F2xcnqQbxCtatZwtJqoforBC79qULilLjtBAzhESV9rMwDFw19rW6 qMPqZh2Zo9ltzpeKbtzqC5M3Nf3wuCZOIFV9VdQO334G81telCpbUn X-Received: by 2002:a05:600c:530f:b0:485:2ce2:4c87 with SMTP id 5b1f17b1804b1-486febb455dmr42143615e9.4.1774006125654; Fri, 20 Mar 2026 04:28:45 -0700 (PDT) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.216]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-486fe836784sm49869935e9.13.2026.03.20.04.28.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2026 04:28:44 -0700 (PDT) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, Frank.Li@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com, john.madieu.xa@bp.renesas.com, kuninori.morimoto.gx@renesas.com, tommaso.merciai.xr@bp.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 v2 2/7] dmaengine: sh: rz-dmac: Add pause status bit Date: Fri, 20 Mar 2026 13:28:33 +0200 Message-ID: <20260320112838.2200198-3-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260320112838.2200198-1-claudiu.beznea.uj@bp.renesas.com> References: <20260320112838.2200198-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 be reused by the code that will be 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 --- Changes in v2: - fixed typos in patch description 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 8148a1c78e12..32349d214f68 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 { @@ -825,12 +828,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 @@ -843,35 +843,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 Fri Apr 3 08:22:42 2026 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.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 5CF393A75B5 for ; Fri, 20 Mar 2026 11:28:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006130; cv=none; b=sd6VjqHzUfq8luv5kLkGIzd0b1sgiqw0WQUg5DTenGwS1CwNWxxRQhMg4sWW366nct6YkAyzufIHbFsG4VqOc04dsu3hbBvxGBZ65YqLweVWQZa0aMXvG256XFoUjDm4ErKAi4sYvKZqoJb1P6yDB8cswZqVIe3mCBQcvU1WVCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006130; c=relaxed/simple; bh=GD9E2/SQwtIIE1eJkpGHpxa3R5g8LJo5xRqW215y1pQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pTWNMqvEMGTtmKq6sdLb5eePQGB77gjoshA7+mLQYesvCEa5Ggq7kfpOH+C94OUDIxG2nrM3gobQPUEGqHKo3nLPncPGoixBj8pHBLSnrEL4HSyGsCGqVZt1PC/QORhOXe1crGrNT/0+Tb7yAP2gcq6d+KoU0RYGVyJGOlVLxRM= 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=SkFXGbql; arc=none smtp.client-ip=209.85.128.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="SkFXGbql" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-486b96760easo20837805e9.2 for ; Fri, 20 Mar 2026 04:28:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1774006128; x=1774610928; 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=nZSF6Phsi5Ep6XqjzxpapK7aNLJkF/Hb03hbbBTs8F4=; b=SkFXGbql1tHWC0FQoTE5nLfAzdcerDWpmihpAW3yl3f7vb5v8AD+AYjbyCK6p6pVHE FYyHiRPruswVsJ8bcnWKIQ6bPoEi1qeSytHvw+6+pxIVEXR3Lr04b5xm0W1Sc6sAxxJ7 ZjVk7bRRVmQfuSEnUca1dsFdNfCO1Fx5prX9mo+Wdo/fFiNkqomspFPB9ajZvoqGHGEq GUQSk6BCI7HEPbG0bnpwlzvEYugZJu0rXkGJWO+7Fcl3sxnlzLboOdFsq+e6oNXEhtU/ Lg3CLnWrCGwlqyBXm2BrOYoI+fcfKpOYw98AwJFb3MYlvBgQVcjYM796xiFdd41ibMTX BcUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774006128; x=1774610928; 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=nZSF6Phsi5Ep6XqjzxpapK7aNLJkF/Hb03hbbBTs8F4=; b=VaozWC02p4GVeTM46TxWpVFyV7180OGm7rjxUf/HsIAoAfmj6sFIwZcPx5+lf9C0uQ 17gKIt/VxgKI9aUTRsJz4JxF3sF4hAOBWZTqc+0GdITPmSYjyCbPbOI+ouJuJDPMdZRq kUqLsdpr++8j5FLJ78UgSefpJGzTLhuPIxeI21HyL9xvO4F3Rp8U87L6thIR+82cz08W +Dp2fXskanQo2KaZGticBw9A04JTXy4hHgT9GmlIGYsTWb7CF7OMmjF34b4E7qlvuYFw CrBEgE3xyNvxMczzFASXdLgKTI1LeXA35sOGF39qQj8y3C99MLKhr+2+VzGmVOCvfCFi BEvw== X-Forwarded-Encrypted: i=1; AJvYcCU7fMW2uNj0XOEWekJbsDT0JjSnyqzvmcMw2GRzdACeKQqOt8Weg1dWVVBgEZgfQYGKbxljaCkv933krxI=@vger.kernel.org X-Gm-Message-State: AOJu0YygCNw1yWNwbQTj7IQKY/RqGj7g+RXloa/t7c5pIGSpweEoiUNf gKlQURZWmuAH9RzdMXYWsfWi6g6KuyrYr3CEjJ2kUl1QYKWMDZCIhhk2lGE/9Bw75Yw= X-Gm-Gg: ATEYQzy2iOshFay/st4RUGIPw6FTrZauxt/DBZENPVmyDf3w5js7/r71OZGPfi7QJ1/ TxgtOAgHeJjuWpKbx1x8Wp0BdjuJKFMFzuOycRFUpQeNyCgFObJ58tMIr4hwNP3GUMZgsGiKRJq jU3//4ikTD+XOyHJtMShPKwBcZ0dNAg8n3sQwc7ULfj9vhgQ4b7TNd1FNJI2HOf1LPR+Z7FFaud NH4fS1bK1SSV/MemwNh+3Lgst3AaEouT5fBNrpjjfQm/bMjaIGjxZ9r2DZvAY71am6qmNTBEt/w yqfdo1thtoSHqmUm/9OwQsC3qi3caNidjWNjsUYsAbqcH7AFVNNE6IP+lGU6shAK4N0EkW6g9lD XniJCd8KV46W8cvo+/8a6smNMzlQYcjlEfkHMaj4MmoB1s4jDYkwbF35Hcu9/ZLZxp5G3gtXZcD 9KFvO06LXSR3lI/wq1kNUn90KN5Zi2A9FzqqZeI2tSqjEz4mgN84BG X-Received: by 2002:a05:600c:c493:b0:485:4388:3492 with SMTP id 5b1f17b1804b1-486fedbd0b0mr40251935e9.11.1774006127646; Fri, 20 Mar 2026 04:28:47 -0700 (PDT) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.216]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-486fe836784sm49869935e9.13.2026.03.20.04.28.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2026 04:28:46 -0700 (PDT) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, Frank.Li@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com, john.madieu.xa@bp.renesas.com, kuninori.morimoto.gx@renesas.com, tommaso.merciai.xr@bp.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 v2 3/7] dmaengine: sh: rz-dmac: Drop the update of channel->chctrl with CHCTRL_SETEN Date: Fri, 20 Mar 2026 13:28:34 +0200 Message-ID: <20260320112838.2200198-4-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260320112838.2200198-1-claudiu.beznea.uj@bp.renesas.com> References: <20260320112838.2200198-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 in rz_dmac_prepare_desc_for_memcpy() and rz_dmac_prepare_descs_for_slave_sg() is unnecessary in the current code base. Moreover, it conflicts with the configuration sequence that will be used for cyclic DMA channels during suspend to RAM. Cyclic DMA support will be introduced in subsequent commits. This is a preparatory commit for cyclic DMA suspend to RAM support. Signed-off-by: Claudiu Beznea --- Changes in v2: - fixed typos in patch title and patch description 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 32349d214f68..58446726afb5 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -368,7 +368,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) @@ -417,8 +417,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 Fri Apr 3 08:22:42 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 245C33A9D9B for ; Fri, 20 Mar 2026 11:28:51 +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=1774006133; cv=none; b=B08tAAKLXjju+z3qPSOgvxmmZsgiNRF0sBpzjR5HdZwCD5ZROkwbWtGI66vVPBmkppiOvKgc5eBrttWkXb2Grm84Q7c3d/Fm4CcB0Jn8KpvjVmFoXcxUEnyUU74Lrf/M6zHAH6+Mv/RKZo4Q4CyuHtVjjdkhvVCGezcdzd9ATw4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006133; c=relaxed/simple; bh=h9pis3uIgjZhaRaP43lEEeFj11msn/IipYbHvWci9FA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UFiKxO1LgoarQvLZnkA+oZqQfusRgzL/SyDcoRfCbEaJNVLA72JOZIzytUl4rH57P9C3+xS+Pik83tUF/No32jPlUIivQJe5ILlBwVY7aUNgPPb1MuW3Cd0b8PM2sCUKP5JKamTZ32TK/RLkkvCReBOWLNSdVzGEl12TlfLHyD4= 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=bURoJ+pK; 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="bURoJ+pK" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-4853e1ce427so4882835e9.3 for ; Fri, 20 Mar 2026 04:28:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1774006129; x=1774610929; 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=/ZMErGYEzh9D7FYJyp2n9bFibDdiom/kkDB/CVaUYJE=; b=bURoJ+pKketoBIokqlwRR5hQUPg0ubQM1wqQj7AG29KxSkBuWkvaKAXOCToFWmok1g JH7sxqpuWMi5X1QslDGEmVolGkv5RT9J6WwcMf2WJMF9qemHN2VoRafI71FgABdoVINw 7E8BlYaKsce0ic12kDLbr5IAaubxUqXuMH8F6kvDvv+MyJ8lFAGck6DOirUj6UAxjNvC 0crt7smAFW4rnXyU/3Nu/EVyOJtWR02T/di2F5DvNIwLNAQU2WFEB9FgPhen+DLuJLq1 Ry9IfMOOSmX70tSPGhiMfwJJ6xuM0ZQyy8UG4hhhd8wLeq+0iJovh9tc2sMTmCLr0wxl cOOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774006129; x=1774610929; 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=/ZMErGYEzh9D7FYJyp2n9bFibDdiom/kkDB/CVaUYJE=; b=gIK/+GDkNXp8qsNWjHTI4cfGGH4Eb5Hq9c65b9EpTqw0hq35QGmcIpPEE851mX2oOm LXw2lplTuxUO8nhzB886lepuEIP040addKcsY+gY2ait7xKcsPFPDaJXAg4F1dYOZuQt +wEdRF1FVsXDdqdHKuSt1UH4oXKZ0iBsdxRBzDWTO15Pl6sS4MgkkvWzrGRNOjGTu8mM q3+WWD2HeHxk11TsINtKXBbxBWMeHiVm/Op8CZ+NOVwrOAucqxunYvpl8foU0iHP2wPC B171s2Iuf/mn/qYf7eInXWCUYt/CDjNbo44eTtjMPQwSUEWtYnr1QyWmbrO8iCWwhttE P8eA== X-Forwarded-Encrypted: i=1; AJvYcCVqjFBnO3kdzZgxHUlaRLi9030/fMuIjqT7Q28d3kACwGYBNXILFAd1Mmh7Vahqkrlj4wYkswISVmhKlqA=@vger.kernel.org X-Gm-Message-State: AOJu0YyRInkPwPYmYXMUHPe/3BnDO27fSmZSjljCIqVIVuXcYjMDo4SE drRwMVx5h6v+L7HV8bLYhUqvY2YRNpUlx5kxztBVwh1wDwyjyPWB4Z+qgsKamSBousk= X-Gm-Gg: ATEYQzyOzYGelfJ+up6byLCFqB1cxIH3s69jeny5sjsrjpU3YNhXU/7BKBjz1H1wNst Tg/4xPtoNxNKh8fZw6bM4KEtNypexGQm7gRSWtJOaiCG8wrEuWqJS6ev9zTGYfijEPhihJTaA6k KOelYpp7l9qqf4kKPDS32iMmC+kVAkweqd68MFpBR/IK8ELMgUbe1cFiIpXnNs/FytK9MLg6KdE nQT5K67kW+Ge939aC6Va4ApMwcMDA+69+malvJaSr8Hl7vjvQqrW2Ak9tnKSaK8rfL4sUqPL3Sc jY/bARRBdNBuDhWvr0+B12lJw//80hEC3Ly2U5PTLuXu4XHeYSbipcG0S0YAc1tyhUP4+H0khk9 zHWvBFvJ+YPZodh3DtAtAwSttmSHjYaF5SYSA8Ng4o7ORFIGp7lxkdGRNGK/CTRmrdZI39fLRlN aDMfO5F/1VP43I798a974BSCYTkYXh6TilaXeMbD06a92SeX3LuDVF X-Received: by 2002:a05:600c:548e:b0:485:3fa9:358c with SMTP id 5b1f17b1804b1-486ff027c33mr41401235e9.17.1774006129463; Fri, 20 Mar 2026 04:28:49 -0700 (PDT) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.216]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-486fe836784sm49869935e9.13.2026.03.20.04.28.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2026 04:28:48 -0700 (PDT) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, Frank.Li@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com, john.madieu.xa@bp.renesas.com, kuninori.morimoto.gx@renesas.com, tommaso.merciai.xr@bp.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 v2 4/7] dmaengine: sh: rz-dmac: Add cyclic DMA support Date: Fri, 20 Mar 2026 13:28:35 +0200 Message-ID: <20260320112838.2200198-5-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260320112838.2200198-1-claudiu.beznea.uj@bp.renesas.com> References: <20260320112838.2200198-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 --- Changes in v2: - none 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 58446726afb5..ca8c0aa8ae59 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 @@ -419,6 +424,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; @@ -439,6 +498,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; } @@ -573,6 +636,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); @@ -723,9 +832,18 @@ static u32 rz_dmac_calculate_residue_bytes_in_vd(struc= t rz_dmac_chan *channel, u } =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); @@ -964,7 +1082,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, @@ -1231,6 +1357,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); @@ -1242,6 +1370,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 Fri Apr 3 08:22:42 2026 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (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 F26CA3A785F for ; Fri, 20 Mar 2026 11:28:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006135; cv=none; b=mGOswzakMjjkjrMcUGm9+C3PXr5H96N6Eb41k/GHEKj8AB2tq/MyI32d0PdUdmqBDG1QtgzrsPSY72qf4eMTN6R1rKkYfiTprnBnrm/2x86g6sShyWF1Q3gd0/UqIvUeq9EpIiIVC0tpraliQ5pJ+806OA7zQ9M0IU1RXnZzQpA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006135; c=relaxed/simple; bh=8W8B7IOd8EkL9ZxUe9bYG4G40slTwd/W6qN26L0cJfs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W8+h1CGZ+EcdPF3jD3wuATiLi43u4lKQO/zi25BuHKBnkwAfHRCUcNHrxBB4e7Kmidkfp8ICygMvBOsuvmc3cU4j/CKy34tBvbpjOOc70aTgI0MYlYtFI8NK6NbDUnXct3l9iR0Ak2vNBdIylM/G4OH7uqK+QOh2v3v6Mr9Ukcc= 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=XwKMm19E; arc=none smtp.client-ip=209.85.128.43 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="XwKMm19E" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-4852f8ac7e9so18039685e9.1 for ; Fri, 20 Mar 2026 04:28:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1774006131; x=1774610931; 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=/rHziFuJH0O/h8GS9IhPrrtY5hqbHqGAKO0ZR1pWFq0=; b=XwKMm19EF1f6+dUkf+axH13Br3z7haOiYC5QilJ+Tl/vgnIyFCLsJssD/VqS82z+Np spXclsqZe1LU/Mw4KSq7EZPLwQrsvrRXIdQfpMoFb8XWu7IKQ3EnfFWNFDsVgRooeR8R wYkfCxK89g9aXiCcGZNgzBSrkziWuHhv/zQmmfDMR2atwk+7fJF3qHQfw344Av/h+YJY tZ5JDtH/MMMJsnXEncL/iEbr0E8uUSkJ2SKWq6qDY+HR5XAkfkmViLJaDOJHZPAMlASf azhpzg1Q1batZdKRR4QpyR8QRpRNAC10hY41hV4AkSUuJ0xzZgXk+w0I+j7pQ5JzrZdL k8jg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774006131; x=1774610931; 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=/rHziFuJH0O/h8GS9IhPrrtY5hqbHqGAKO0ZR1pWFq0=; b=mQ5DgPBKxNXZ4jBSiQtxTVZIeEJTM78yDiGJRnl7btzeEuL7P+OAEbbRODZiC0BQlD vLjSlgmGStrfsRgRSp5biNCPbEtipmj39Q2BEwBuvp/JAARRS+9t7FZ5pbH9BOS/ZdQ0 NPew8avT9zsJF/t59895XOI4sZ3SCAoBQInKdAQei9mD0F1cJ0eMU+H7IHDwsPmDtXIj NF4YTCxXW9EptISP+wPiaT0fnMpwOb3MNNdfZ/TvRrqhm/JJqBJNzZ4vymejtJ0QuRFJ TEnOhzyloy1xV/MmjBAIA5AWFM/Pkai1ZoUZZxYD6KaRgdEdinNLTDDyqv83pwVHuaW3 /wRg== X-Forwarded-Encrypted: i=1; AJvYcCXGLzBFsN4frKHf3BLXARlX/Esr/pPjotnggoQf4yZmku2Dh6kq4IT68F2Ipe38sGSAv7PtYspz8bjXBZc=@vger.kernel.org X-Gm-Message-State: AOJu0Yz/qmxmH5HLVyX0U89im/GTBw/NrpZa9heDzZihUa2fRq6ZEznH 9XR8D4Uxu3kJ1U02nu617M7+vZ4uIsKoInVY08OfTugmHo4iMNnsFU3eh0UMbsfGSvc= X-Gm-Gg: ATEYQzyNPxseO/+ZaQDyYCGOYMbD/STFLiBeaGsJHvO1sGwzTZSzk3JD7hJtwnmKbyq QHr7D3Nx0nU4+5VwxsXhEatiTAo3fzlzDZoqmW63MqEFOrj4FMzwP6yTjAuNs/4Y0iq3pe4Z3PM 0RBXnDuQb9WPBMZX1MNvMi07/GBGn08MwtVmMAYeflxg0HoHLhESSvKgckopgyq+yqIzcOkGLm9 zme4EoG9KOOu190JtRk7yHbvXd2D/KJnnuWjR8oaDsKtNS85klMNA//s3Sh/SFGhNVNru77tTt0 jv3gx6Vz+JwwBHeuGrVXXaVsws57dC3vUsEr5oXmezHjncWFOfdrkxkyr7Vc/Tfs6i9xy3mIK6c /dhDCkaoM93JS9GAzzl7nRt8vt7u6Shs9XH4D+cqSi98MJ08eSqdmt76gakQDLcC4n+t54CR2Ib fRhy/MJ0Icrmlk2V1YRoSVL8F3g21BBCjMbPSldjznAIP+rbdu+/re X-Received: by 2002:a05:600d:8401:b0:485:35a4:939f with SMTP id 5b1f17b1804b1-486fee297bcmr29826535e9.28.1774006131195; Fri, 20 Mar 2026 04:28:51 -0700 (PDT) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.216]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-486fe836784sm49869935e9.13.2026.03.20.04.28.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2026 04:28:50 -0700 (PDT) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, Frank.Li@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com, john.madieu.xa@bp.renesas.com, kuninori.morimoto.gx@renesas.com, tommaso.merciai.xr@bp.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 v2 5/7] dmaengine: sh: rz-dmac: Add suspend to RAM support Date: Fri, 20 Mar 2026 13:28:36 +0200 Message-ID: <20260320112838.2200198-6-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260320112838.2200198-1-claudiu.beznea.uj@bp.renesas.com> References: <20260320112838.2200198-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 of the 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/resume, the driver restores additional registers for these channels during the system 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 the ongoing transfers to complete before allowing suspend-to-RAM to proceed. Signed-off-by: Claudiu Beznea Tested-by: Tommaso Merciai --- Changes in v2: - fixed typos in patch description - in rz_dmac_suspend_prepare(): return -EAGAIN based on the value returned by vchan_issue_pending() - in rz_dmac_suspend_recover(): clear RZ_DMAC_CHAN_STATUS_SYS_SUSPENDED for non cyclic channels - in rz_dmac_resume(): call rz_dmac_set_dma_req_no() only for cyclic channe= ls drivers/dma/sh/rz-dmac.c | 185 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 177 insertions(+), 8 deletions(-) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index ca8c0aa8ae59..6f83ccdf94c6 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; @@ -994,10 +1002,17 @@ static int rz_dmac_device_pause(struct dma_chan *cha= n) 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); @@ -1005,14 +1020,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; } @@ -1026,6 +1060,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 @@ -1430,6 +1471,133 @@ 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 (vchan_issue_pending(&channel->vc) && + !(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))) { + channel->status &=3D ~BIT(RZ_DMAC_CHAN_STATUS_SYS_SUSPENDED); + 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); + + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC))) { + rz_dmac_ch_writel(&dmac->channels[i], CHCTRL_DEFAULT, CHCTRL, 1); + continue; + } + + rz_dmac_set_dma_req_no(dmac, channel->index, channel->mid_rid); + + 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, @@ -1456,6 +1624,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 Fri Apr 3 08:22:42 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (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 B68ED3A9D99 for ; Fri, 20 Mar 2026 11:28:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006138; cv=none; b=RfDErtyWlMPxpvyuDk+LK3RjzGg53wWlL0z/U6RYTUPuFsrrrBImUvDzBe+s4IyzhTum+kz+Df2WL9V/6EVUh5cA3ZYLWUbNJ704/6q00DQPUJULi1gvvAUgMopI53mg9/CBXOO44tNj9RhTRwQuy13+/r01zvoilXJWwWwkhP8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006138; c=relaxed/simple; bh=NnzKXwnWGQQQ3whvjWmvFZigOw+O/03c7ufBbfgWUgc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Tge3TvQzue1ZlST7d6FSOeQ/YyvwYTHhpc3oD3y6s5EfljRg+ajrfvj/D/WWttQTyOrMaRvr6fkNgQdW/I4xw1gkyGWJDQBQz/+btPDG7bw2wHkzGLB0ro//+TCqDOp8cOUA1BfelgwZLmbeeuXw7gWePAm3A3X2So6sFn+xrQA= 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=lFWwnqTu; arc=none smtp.client-ip=209.85.128.54 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="lFWwnqTu" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-486fba7ce4cso12748995e9.3 for ; Fri, 20 Mar 2026 04:28:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1774006133; x=1774610933; 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=k0xpkz8kW8qz6GQ6c9rVCkQ35YtTL3mTNminOSXRTKU=; b=lFWwnqTuK55MhJGnwr619Ckf6tcmx1NzzWvNKcYnXWpDJ/zkUIfhGm3rwGzDv0Fsho AALI/PQi3vGxAI0jhxz1u6WtdnianA2B48lzGbL1aedchvKwjgkhYWzmWJOo8/gYYLwN gEmiDU9QAxMl8nQH9gy2xV2LnTO1ZENV3ItIPYp18ctIzkcQ7OFGk9gHpusfqQ/ov/sT THZD77hX3rGxpFqm7GmHHySJo+5YVrsqSuqHM5XgvuzDB4QiQ6u7ALefsl0ByNp5TINw TMOWUqR30GjSoCBU435N4LNT8z5hP9cqwKqciOXTx6YrbBib5jzZQNqIl8TQNMV98bSK Ui7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774006133; x=1774610933; 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=k0xpkz8kW8qz6GQ6c9rVCkQ35YtTL3mTNminOSXRTKU=; b=J9qUSc1sf52TUDpKDdG5EwqQR34P1lYb0lxzRmgZ7aWArvzOS7Pch8c8xnmvoadPTB gHei4d3enhdXKm7EdZ0YU1daP84XzhGFX1sJ2ai5DBNkwQrgXrtP9Bt/74eJYeSL7vuB nvLt8lYLsEAsfANlPNQXYG79ATwJn5+zfpcb07Hif9IWtazERiECOwSxv08xq8827cxJ M53hg10/Xo3dm/hvuZQ7HHXVxkSfWM7/7UeFnClJqEd6gd5DKtFUmY5dvAj/PsbvXLhB QDfvsYM2oRWTiNkfvnuDrzw2XA1MpeiCfDfmx3N/H8ilc+SC2VVhkw+9vOX01L+d6Q4g jlAw== X-Forwarded-Encrypted: i=1; AJvYcCXc4Nm9RCsyxbYi+KxOizRmdYOsqcBSZGt4xQmRymz23fsrnGyrBukd/COHob2qDoLCgekfyr+RrwA0Z/4=@vger.kernel.org X-Gm-Message-State: AOJu0Ywju2by6DUfhK+vYA76K3QLLWGLsDJYUEapryZCB0zApb7k07QB p5GT9TyC4jJJravQujrofg2Zi82vmwm2pBssZCkJ6FJbt3hC38b/W2PkcZmBq38OYGo= X-Gm-Gg: ATEYQzxDEI9Rb9szlRj/7lWCanLXaUQyzqjC0M9PQmWb8RdI3yFhp+43svKPtRYGlOG cx0Cel0zLGXR34HM9A3CRag6z5oe+Vb3lgWfHMYQWzTbc+198VmpqivO4ukNKBKxHSjqAlwdsK4 XlEURyaPo0io8BX6CbTYyf6Wg5TfHKZEzFHSJgAtQZq5+d0IwfxfjmKnIyX6Cau4lbF3FLOOOsL lOdNi+YEihKZZWeole46TwOH2R9Zc38BebZDcQIMz1Yx6DwcKigBEiqdltqb+ki9hxyZCZq+URq xAY8Eghw6RxfeBA+Dr2vR/ahLWzCilKQxfC5n0tQHwBMcARv2vzceVnwLmuUonk3udrNMRVUN0D pHLltnMsi+npKmlEqX9pHl86MXcwgoGOZO2IjDkM5HBuVFpehNlgjm/qu+TB+SIklp1gkSEgCCd 9XC06xRNQY+eDzkn7j3uiOWprLGhy/IM6D5qKsyCafu3pBVR6MJpFm X-Received: by 2002:a05:600c:3b8c:b0:483:b505:9db7 with SMTP id 5b1f17b1804b1-486ff03f4d3mr42910705e9.32.1774006132920; Fri, 20 Mar 2026 04:28:52 -0700 (PDT) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.216]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-486fe836784sm49869935e9.13.2026.03.20.04.28.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2026 04:28:52 -0700 (PDT) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, Frank.Li@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com, john.madieu.xa@bp.renesas.com, kuninori.morimoto.gx@renesas.com, tommaso.merciai.xr@bp.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 v2 6/7] ASoC: renesas: rz-ssi: Use generic PCM dmaengine APIs Date: Fri, 20 Mar 2026 13:28:37 +0200 Message-ID: <20260320112838.2200198-7-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260320112838.2200198-1-claudiu.beznea.uj@bp.renesas.com> References: <20260320112838.2200198-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 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 long) 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 --- Changes in v2: - fixed typos in patch description - select CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM for rz-ssi driver - in rz_ssi_dai_hw_params() check if DMA is enabled before calling snd_dmaengine_pcm_get_chan() to avoid failures for PIO mode - do not drop rz_ssi_pcm_pointer() and rz_ssi_pcm_new() as these are necessary for PIO mode - added 2 struct snd_soc_component_driver, one for PIO mode, one for DMA and updated probe() to register the proper snd_soc_component_driver based on the working mode sound/soc/renesas/Kconfig | 1 + sound/soc/renesas/rz-ssi.c | 348 ++++++++++--------------------------- 2 files changed, 93 insertions(+), 256 deletions(-) diff --git a/sound/soc/renesas/Kconfig b/sound/soc/renesas/Kconfig index 11c2027c88a7..558f9d890165 100644 --- a/sound/soc/renesas/Kconfig +++ b/sound/soc/renesas/Kconfig @@ -56,6 +56,7 @@ config SND_SOC_MSIOF config SND_SOC_RZ tristate "RZ/G2L series SSIF-2 support" depends on ARCH_RZG2L || COMPILE_TEST + select CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM help This option enables RZ/G2L SSIF-2 sound support. =20 diff --git a/sound/soc/renesas/rz-ssi.c b/sound/soc/renesas/rz-ssi.c index 71e434cfe07b..d833ff83caf6 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,10 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substr= eam *substream, return -EINVAL; } =20 + /* Save the DMA channels for recovery. */ + if (rz_ssi_is_dma_enabled(ssi)) + 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 +868,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 +894,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, @@ -1113,7 +954,7 @@ static struct snd_soc_dai_driver rz_ssi_soc_dai[] =3D { }, }; =20 -static const struct snd_soc_component_driver rz_ssi_soc_component =3D { +static const struct snd_soc_component_driver rz_ssi_soc_component_pio =3D { .name =3D "rz-ssi", .open =3D rz_ssi_pcm_open, .pointer =3D rz_ssi_pcm_pointer, @@ -1121,10 +962,23 @@ static const struct snd_soc_component_driver rz_ssi_= soc_component =3D { .legacy_dai_naming =3D 1, }; =20 +static const struct snd_soc_component_driver rz_ssi_soc_component_dma =3D { + .name =3D "rz-ssi", + .open =3D rz_ssi_pcm_open, + .legacy_dai_naming =3D 1, +}; + +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) { + const struct snd_soc_component_driver *component_driver; + 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 +992,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 +1015,28 @@ static int rz_ssi_probe(struct platform_device *pde= v) =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) { + 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_present(np, "dma-names")) { + 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); + } else { + ret =3D -ENODEV; + } + + 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; + component_driver =3D &rz_ssi_soc_component_pio; } 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"); + component_driver =3D &rz_ssi_soc_component_dma; } =20 ssi->playback.priv =3D ssi; @@ -1182,17 +1047,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 +1094,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, component_driver, + rz_ssi_soc_dai, + ARRAY_SIZE(rz_ssi_soc_dai)); } =20 static const struct of_device_id rz_ssi_of_match[] =3D { @@ -1304,7 +1141,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 Fri Apr 3 08:22:42 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 5175C3AB26D for ; Fri, 20 Mar 2026 11:28:56 +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=1774006139; cv=none; b=RlxPPN9IQsW4TTOUEnFXHlXFrXb5rpktNRp070MUsnu8erP7mduwVgZ66hLymSphTkZQhmkQJVjlcgnriD0wR0fJdLksyt7nuDyOokDKKMf/vwVjXvBpj15tImktZq9FzEAJpBPUF9M75KIsYluHiShatMM0GLcIuOy0n+H2eTE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774006139; c=relaxed/simple; bh=ZIU6VE1rdd8h/W/u6JZmxearSKQT4cdulYKTOXV8vf8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ckiTRNtwpyu00F2rIVaz+LcW5SrweyPhp/EqOrJKSjzgE1w1HJzyOu9aOsgqqYph/heh3Ek/RDqCe3tx7RFs5DvXHwBFWwVyyp8Nw9FtmBvBkqqjCYOHj06ehknv/zy8Jx7iiSzOUVFUDb5Gz44iK6ZAQCCvwkcWss783DG23n0= 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=Ln7tn2Vd; 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="Ln7tn2Vd" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-4853e1ce427so4883595e9.3 for ; Fri, 20 Mar 2026 04:28:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tuxon.dev; s=google; t=1774006135; x=1774610935; 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=QxH8LfUYZeKM7Jz/vL5iiWORgbu1oqnI0wnugAc7pg8=; b=Ln7tn2Vd/xaWBuZvnC1Dv00t40u9P+GmGV07DSu+KOAtQlDjpa1fxTTlSEDSxazW3b vjkF6WyY+IGyWf+7ug36rmplxFq8Wd+rPBqLeP0kgs7pN3oyXI37s7yt2sbm7sRyyWLA QsTeWrzSrnT91cx5GABhVPQZFvkrjH+ghaplkdz6kr6nc49XRZ3bYuKztfQDx1YhooO/ GHvbtGZe1tsDKo1FpIaWrG3qEkkBSoLV2TiLQ0XDu4Rr0QTctrt1zYdZoPVdmvT+mAh8 4x4n0h4b/Ia8Coy9yI+rtElrALojjs93n8eXkT+TC0WDVielVaNSaV9teeGieeN1dETK rDpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774006135; x=1774610935; 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=QxH8LfUYZeKM7Jz/vL5iiWORgbu1oqnI0wnugAc7pg8=; b=dX+dHoJjipb7lvurFLVTAohrL0c4tAnB+fO6irqiLcREjvhAAdTAfE6O1YAfjYLLtm sRyhZZATP7iechC0Tllvbcp+TYJA/jzcU1wzi6QVvVqcRg4sNToT2LFWQQ2GZzQp2lVr hYbsvXxRyGEbx02kWPZABpKVoeKYH9mjs/p8YKMrLzxx79nCAhj+XqJvor4o14cLFHvs i1v0U4+KU6giAdjatt1tDz4lDvn/3kWdYttRka5eo1jdZaSTtRgT0WCgVhpNWU3BHIxQ squH4lOMsY0XlwTVzHnxjcy0p6irexw8D0HKFCVsKEHHRNelnRjYDIFhSMqhQD/+8WLR su0g== X-Forwarded-Encrypted: i=1; AJvYcCUwu554ZfdTinPzYxWFGMVSTMh0zpLD6/byM9SuLyXh4kJkNBIGByg0b8pcg2uzpTcU/Kh3yywFNkDklDc=@vger.kernel.org X-Gm-Message-State: AOJu0YxI1nevbMNdJSTnOpIS/M9qVkAQdRo/Eo21ZmAScy6NZNn0bCMM BOLVNLTaUpmKXbwYtOs42UXxlt6EAZqnWDceyEmjtLlw9BcP1CzNfy9QKfw4gaMglcI= X-Gm-Gg: ATEYQzyi8yqzX3u+Ky7UdEiXnG85WGJ5kwUjoPhlqG/59XrxS2XLH05pyGIYLPEo6L+ IjHGUYBWD8vWhVziJ7G2p6cRSBVSzfiCnFZtdGY6/qg68VniqvY1K2Spgm3T2fmM8B5FPu23vkC ytGR7u8Fcnw+EzLFIf+OLdNHiDq5h4Qam1eYCsN8ke4vf1f9ys2vNSt0RsiJs243GNnat7vJsQV zCUak4wp8O4gIM6WElzkX+i/b4ez3G4wbpgaOYkXqXUKLJWlRmEOXp4ULNfHN+1SYL0ycRGXXNo UeMUQrctwrThwQEe78qJ+K/R2m2jCHpJVLwKvya5xQh62noP6wfSS1woco/Fx76iBFj8nM8fCA4 AXEdUJS2Y8yj2FIt9JN/n7wJX3a9ivG0fG/uW3bBhWzOKigOirK4VRbr6D1mHNaJeMXsFd+tWjc 3PWdBszdrmHDvF5qKkq0F9aTmGwE6wJAaa68DYV9mDqgSb6x9uz8b5tzdm9xuz/yg= X-Received: by 2002:a05:600c:1e09:b0:485:4526:ee06 with SMTP id 5b1f17b1804b1-486fedfb677mr41638975e9.11.1774006134684; Fri, 20 Mar 2026 04:28:54 -0700 (PDT) Received: from claudiu-X670E-Pro-RS.. ([82.78.167.216]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-486fe836784sm49869935e9.13.2026.03.20.04.28.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2026 04:28:54 -0700 (PDT) From: Claudiu X-Google-Original-From: Claudiu To: vkoul@kernel.org, Frank.Li@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, biju.das.jz@bp.renesas.com, prabhakar.mahadev-lad.rj@bp.renesas.com, p.zabel@pengutronix.de, geert+renesas@glider.be, fabrizio.castro.jz@renesas.com, john.madieu.xa@bp.renesas.com, kuninori.morimoto.gx@renesas.com, tommaso.merciai.xr@bp.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 v2 7/7] dmaengine: sh: rz-dmac: Set the Link End (LE) bit on the last descriptor Date: Fri, 20 Mar 2026 13:28:38 +0200 Message-ID: <20260320112838.2200198-8-claudiu.beznea.uj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260320112838.2200198-1-claudiu.beznea.uj@bp.renesas.com> References: <20260320112838.2200198-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 --- Changes in v2: - none 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 6f83ccdf94c6..95a89c9d2925 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 @@ -376,7 +377,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 @@ -418,7 +419,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