Re: [PATCH v6 18/18] dmaengine: sh: rz-dmac: Set the Link End (LE) bit on the last descriptor

From: Tommaso Merciai

Date: Thu May 28 2026 - 10:47:09 EST


On Tue, May 26, 2026 at 11:47:10AM +0300, Claudiu Beznea wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx>
>
> 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: Tommaso Merciai <tommaso.merciai.xr@xxxxxxxxxxxxxx>

> Tested-by: John Madieu <john.madieu.xa@xxxxxxxxxxxxxx>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx>
> ---
>
> Changes in v6:
> - collected tags
>
> Changes in v5:
> - none
>
> Changes in v4:
> - none
>
> Changes in v3:
> - none
>
> 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 2a7124e4aea3..f1174d25da84 100644
> --- a/drivers/dma/sh/rz-dmac.c
> +++ b/drivers/dma/sh/rz-dmac.c
> @@ -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;
> --
> 2.43.0
>