]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dmaengine: sh: rz-dmac: Set the Link End (LE) bit on the last descriptor
authorClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Tue, 26 May 2026 08:47:10 +0000 (11:47 +0300)
committerVinod Koul <vkoul@kernel.org>
Thu, 4 Jun 2026 15:28:34 +0000 (20:58 +0530)
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.

Tested-by: John Madieu <john.madieu.xa@bp.renesas.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Link: https://patch.msgid.link/20260526084710.3491480-19-claudiu.beznea@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/sh/rz-dmac.c

index 2a7124e4aea3abd53463cda3294175298bf19a5c..f1174d25da849db09da9ac0440236e27d6e2ca9e 100644 (file)
@@ -200,6 +200,7 @@ struct rz_dmac {
 
 /* LINK MODE DESCRIPTOR */
 #define HEADER_LV                      BIT(0)
+#define HEADER_LE                      BIT(1)
 #define HEADER_WBD                     BIT(2)
 
 #define RZ_DMAC_MAX_CHAN_DESCRIPTORS   16
@@ -382,7 +383,7 @@ static void rz_dmac_prepare_desc_for_memcpy(struct rz_dmac_chan *channel)
        lmdesc->chcfg = chcfg;
        lmdesc->chitvl = 0;
        lmdesc->chext = 0;
-       lmdesc->header = HEADER_LV;
+       lmdesc->header = HEADER_LV | HEADER_LE;
 
        rz_dmac_set_dma_req_no(dmac, channel->index, dmac->info->default_dma_req_no);
 
@@ -425,7 +426,7 @@ static void rz_dmac_prepare_descs_for_slave_sg(struct rz_dmac_chan *channel)
                lmdesc->chext = 0;
                if (i == (sg_len - 1)) {
                        lmdesc->chcfg = (channel->chcfg & ~CHCFG_DEM);
-                       lmdesc->header = HEADER_LV;
+                       lmdesc->header = HEADER_LV | HEADER_LE;
                } else {
                        lmdesc->chcfg = channel->chcfg;
                        lmdesc->header = HEADER_LV;