[v5 11/15] dma/dpaa: add workaround for ERR050757
Gagandeep Singh
g.singh at nxp.com
Tue Oct 8 12:58:06 CEST 2024
From: Jun Yang <jun.yang at nxp.com>
ERR050757 on LS104x indicates:
For outbound PCIe read transactions, a completion buffer is used
to store the PCIe completions till the data is passed back to the
initiator. At most 16 outstanding transactions are allowed and
maximum read request is 256 bytes. The completion buffer size
inside the controller needs to be at least 4KB, but the PCIe
controller has 3 KB of buffer. In case the size of pending
outbound read transactions of more than 3KB, the PCIe controller
may drop the incoming completions without notifying the initiator
of the transaction, leaving transactions unfinished. All
subsequent outbound reads to PCIe are blocked permanently.
To avoid qDMA hang as it keeps waiting for data that was silently
dropped, set stride mode for qDMA.
Signed-off-by: Jun Yang <jun.yang at nxp.com>
Signed-off-by: Gagandeep Singh <g.singh at nxp.com>
---
config/arm/meson.build | 3 ++-
doc/guides/dmadevs/dpaa.rst | 2 ++
drivers/dma/dpaa/dpaa_qdma.c | 38 +++++++++++++++++++++++++++++++++---
drivers/dma/dpaa/dpaa_qdma.h | 19 +++++++-----------
4 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/config/arm/meson.build b/config/arm/meson.build
index 012935d5d7..f81e466318 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -468,7 +468,8 @@ soc_dpaa = {
['RTE_MACHINE', '"dpaa"'],
['RTE_LIBRTE_DPAA2_USE_PHYS_IOVA', false],
['RTE_MAX_LCORE', 16],
- ['RTE_MAX_NUMA_NODES', 1]
+ ['RTE_MAX_NUMA_NODES', 1],
+ ['RTE_DMA_DPAA_ERRATA_ERR050757', true]
],
'numa': false
}
diff --git a/doc/guides/dmadevs/dpaa.rst b/doc/guides/dmadevs/dpaa.rst
index f99bfc6087..746919ec6b 100644
--- a/doc/guides/dmadevs/dpaa.rst
+++ b/doc/guides/dmadevs/dpaa.rst
@@ -42,6 +42,8 @@ Compilation
For builds using ``meson`` and ``ninja``, the driver will be built when the
target platform is dpaa-based. No additional compilation steps are necessary.
+- ``RTE_DMA_DPAA_ERRATA_ERR050757`` - enable software workaround for Errata-A050757
+
Initialization
--------------
diff --git a/drivers/dma/dpaa/dpaa_qdma.c b/drivers/dma/dpaa/dpaa_qdma.c
index 02f8685c48..026ba124e1 100644
--- a/drivers/dma/dpaa/dpaa_qdma.c
+++ b/drivers/dma/dpaa/dpaa_qdma.c
@@ -167,7 +167,6 @@ fsl_qdma_pre_comp_sd_desc(struct fsl_qdma_queue *queue)
/* Descriptor Buffer */
sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
-
ddf->dwttype = FSL_QDMA_CMD_RWTTYPE;
ddf->lwc = FSL_QDMA_CMD_LWC;
@@ -449,8 +448,9 @@ fsl_qdma_reg_init(struct fsl_qdma_engine *fsl_qdma)
/* Initialize the queue mode. */
reg = FSL_QDMA_BCQMR_EN;
- reg |= FSL_QDMA_BCQMR_CD_THLD(ilog2(temp->n_cq) - 4);
- reg |= FSL_QDMA_BCQMR_CQ_SIZE(ilog2(temp->n_cq) - 6);
+ reg |= FSL_QDMA_BCQMR_CD_THLD(ilog2_qthld(temp->n_cq));
+ reg |= FSL_QDMA_BCQMR_CQ_SIZE(ilog2_qsize(temp->n_cq));
+ temp->le_cqmr = reg;
qdma_writel(reg, block + FSL_QDMA_BCQMR(i));
}
@@ -694,6 +694,9 @@ fsl_qdma_enqueue_desc_single(struct fsl_qdma_queue *fsl_queue,
struct fsl_qdma_comp_sg_desc *csgf_src, *csgf_dest;
struct fsl_qdma_cmpd_ft *ft;
int ret;
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+ struct fsl_qdma_sdf *sdf;
+#endif
ret = fsl_qdma_enqueue_overflow(fsl_queue);
if (unlikely(ret))
@@ -701,6 +704,19 @@ fsl_qdma_enqueue_desc_single(struct fsl_qdma_queue *fsl_queue,
ft = fsl_queue->ft[fsl_queue->ci];
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+ sdf = &ft->df.sdf;
+ sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
+ if (len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
+ sdf->ssen = 1;
+ sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ } else {
+ sdf->ssen = 0;
+ sdf->sss = 0;
+ sdf->ssd = 0;
+ }
+#endif
csgf_src = &ft->desc_sbuf;
csgf_dest = &ft->desc_dbuf;
qdma_desc_sge_addr_set64(csgf_src, src);
@@ -733,6 +749,9 @@ fsl_qdma_enqueue_desc_sg(struct fsl_qdma_queue *fsl_queue)
uint32_t total_len;
uint16_t start, idx, num, i, next_idx;
int ret;
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+ struct fsl_qdma_sdf *sdf;
+#endif
eq_sg:
total_len = 0;
@@ -798,6 +817,19 @@ fsl_qdma_enqueue_desc_sg(struct fsl_qdma_queue *fsl_queue)
ft->desc_dsge[num - 1].final = 1;
csgf_src->length = total_len;
csgf_dest->length = total_len;
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+ sdf = &ft->df.sdf;
+ sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
+ if (total_len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
+ sdf->ssen = 1;
+ sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ } else {
+ sdf->ssen = 0;
+ sdf->sss = 0;
+ sdf->ssd = 0;
+ }
+#endif
ret = fsl_qdma_enqueue_desc_to_ring(fsl_queue, num);
if (ret)
return ret;
diff --git a/drivers/dma/dpaa/dpaa_qdma.h b/drivers/dma/dpaa/dpaa_qdma.h
index 9b69db517e..171c093117 100644
--- a/drivers/dma/dpaa/dpaa_qdma.h
+++ b/drivers/dma/dpaa/dpaa_qdma.h
@@ -77,8 +77,6 @@
#define FSL_QDMA_DMR_DQD 0x40000000
#define FSL_QDMA_DSR_DB 0x80000000
-#define FSL_QDMA_COMMAND_BUFFER_SIZE 64
-#define FSL_QDMA_DESCRIPTOR_BUFFER_SIZE 32
#define FSL_QDMA_CIRCULAR_DESC_SIZE_MIN 64
#define FSL_QDMA_CIRCULAR_DESC_SIZE_MAX 16384
#define FSL_QDMA_QUEUE_NUM_MAX 8
@@ -88,18 +86,15 @@
#define FSL_QDMA_CMD_RWTTYPE 0x4
#define FSL_QDMA_CMD_LWC 0x2
-#define FSL_QDMA_CMD_RWTTYPE_OFFSET 28
-#define FSL_QDMA_CMD_LWC_OFFSET 16
+#define FSL_QDMA_CMD_SS_ERR050757_LEN 128
/* qdma engine attribute */
-#define QDMA_QUEUE_SIZE 64
-#define QDMA_STATUS_SIZE 64
-#define QDMA_CCSR_BASE 0x8380000
-#define VIRT_CHANNELS 32
-#define QDMA_BLOCK_OFFSET 0x10000
-#define QDMA_BLOCKS 4
-#define QDMA_QUEUES 8
-#define QDMA_DELAY 1000
+#define QDMA_QUEUE_SIZE FSL_QDMA_CIRCULAR_DESC_SIZE_MIN
+#define QDMA_STATUS_SIZE QDMA_QUEUE_SIZE
+#define QDMA_CCSR_BASE 0x8380000
+#define QDMA_BLOCK_OFFSET 0x10000
+#define QDMA_BLOCKS 4
+#define QDMA_QUEUES 8
#define QDMA_QUEUE_CR_WM 32
#define QDMA_BIG_ENDIAN 1
--
2.25.1
More information about the dev
mailing list