Skip to content

Instantly share code, notes, and snippets.

@r-vignesh
Created March 15, 2024 11:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save r-vignesh/b018a2a079ed48b71ca7bea4741cc8cc to your computer and use it in GitHub Desktop.
Save r-vignesh/b018a2a079ed48b71ca7bea4741cc8cc to your computer and use it in GitHub Desktop.
From aed59fbbd859cb9eb373db1e0eb1d0af7b64b3b6 Mon Sep 17 00:00:00 2001
From: Vignesh Raghavendra <vigneshr@ti.com>
Date: Fri, 15 Mar 2024 16:19:29 +0530
Subject: [PATCH] dmaengine: ti: k3-udma: Fix teardown timeouts around cylic
mode
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
drivers/dma/ti/k3-udma.c | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 6400d06588a2..24a2de1d20ed 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -3185,27 +3185,38 @@ static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d,
d->static_tr.elcnt = elcnt;
- /*
- * PDMA must to close the packet when the channel is in packet mode.
- * For TR mode when the channel is not cyclic we also need PDMA to close
- * the packet otherwise the transfer will stall because PDMA holds on
- * the data it has received from the peripheral.
- */
if (uc->config.pkt_mode || !uc->cyclic) {
+ /*
+ * PDMA must close the packet when the channel is in packet mode.
+ * For TR mode when the channel is not cyclic we also need PDMA
+ * to close the packet otherwise the transfer will stall because
+ * PDMA holds on the data it has received from the peripheral.
+ */
unsigned int div = dev_width * elcnt;
if (uc->cyclic)
d->static_tr.bstcnt = d->residue / d->sglen / div;
else
d->static_tr.bstcnt = d->residue / div;
+ } else if (uc->config.dir == DMA_DEV_TO_MEM && !uc->config.pkt_mode &&
+ uc->cyclic) {
+ /*
+ * For cyclic TR mode PDMA must close the packet after every TR
+ * transfer, as we have to set EOP in each TR to prevent short
+ * packet errors seen on channel teardown.
+ */
+ struct cppi5_tr_type1_t *tr_req = d->hwdesc[0].tr_req_base;
- if (uc->config.dir == DMA_DEV_TO_MEM &&
- d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
- return -EINVAL;
+ d->static_tr.bstcnt =
+ (tr_req->icnt0 * tr_req->icnt1) / dev_width;
} else {
d->static_tr.bstcnt = 0;
}
+ if (uc->config.dir == DMA_DEV_TO_MEM &&
+ d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
+ return -EINVAL;
+
return 0;
}
@@ -3526,8 +3537,11 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
if (!(flags & DMA_PREP_INTERRUPT))
cppi5_tr_csf_set(&tr_req[tr_idx].flags,
- CPPI5_TR_CSF_SUPR_EVT);
-
+ CPPI5_TR_CSF_SUPR_EVT |
+ CPPI5_TR_CSF_EOP);
+ else
+ cppi5_tr_csf_set(&tr_req[tr_idx].flags,
+ CPPI5_TR_CSF_EOP);
period_addr += period_len;
}
--
2.43.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment