[v2,16/30] dma/dpaa: add workaround for ERR050757

Message ID 20240722115843.1830105-17-g.singh@nxp.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series NXP DMA driver fixes and Enhancements |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Gagandeep Singh July 22, 2024, 11:58 a.m. UTC
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: Gagandeep Singh <g.singh@nxp.com>
---
 config/arm/meson.build       |  3 ++-
 doc/guides/dmadevs/dpaa.rst  |  2 ++
 drivers/dma/dpaa/dpaa_qdma.c | 18 ++++++++++++++++++
 drivers/dma/dpaa/dpaa_qdma.h |  5 +++++
 4 files changed, 27 insertions(+), 1 deletion(-)
  

Patch

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 bb6b54e583..a21279293c 100644
--- a/drivers/dma/dpaa/dpaa_qdma.c
+++ b/drivers/dma/dpaa/dpaa_qdma.c
@@ -159,6 +159,10 @@  fsl_qdma_comp_fill_memcpy(struct fsl_qdma_comp *fsl_comp,
 				      dma_addr_t dst, dma_addr_t src, u32 len)
 {
 	struct fsl_qdma_format *csgf_src, *csgf_dest;
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+	struct fsl_qdma_sdf *sdf;
+	u32 cfg = 0;
+#endif
 
 	/* Note: command table (fsl_comp->virt_addr) is getting filled
 	 * directly in cmd descriptors of queues while enqueuing the descriptor
@@ -171,6 +175,20 @@  fsl_qdma_comp_fill_memcpy(struct fsl_qdma_comp *fsl_comp,
 	csgf_src = (struct fsl_qdma_format *)fsl_comp->virt_addr + 2;
 	csgf_dest = (struct fsl_qdma_format *)fsl_comp->virt_addr + 3;
 
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+	sdf = (struct fsl_qdma_sdf *)fsl_comp->desc_virt_addr;
+	sdf->cmd = rte_cpu_to_le_32(FSL_QDMA_CMD_RWTTYPE <<
+				FSL_QDMA_CMD_RWTTYPE_OFFSET);
+	if (len > FSL_QDMA_CMD_SSS_DISTANCE) {
+		sdf->cmd |= rte_cpu_to_le_32(FSL_QDMA_CMD_SSEN);
+		cfg |= rte_cpu_to_le_32(FSL_QDMA_CMD_SSS_STRIDE <<
+					FSL_QDMA_CFG_SSS_OFFSET |
+					FSL_QDMA_CMD_SSS_DISTANCE);
+		sdf->cfg = cfg;
+	} else
+		sdf->cfg = 0;
+#endif
+
 	/* Status notification is enqueued to status queue. */
 	qdma_desc_addr_set64(csgf_src, src);
 	qdma_csgf_set_len(csgf_src, len);
diff --git a/drivers/dma/dpaa/dpaa_qdma.h b/drivers/dma/dpaa/dpaa_qdma.h
index 2092fb39f5..361f88856b 100644
--- a/drivers/dma/dpaa/dpaa_qdma.h
+++ b/drivers/dma/dpaa/dpaa_qdma.h
@@ -81,6 +81,11 @@ 
 #define FSL_QDMA_CMD_RWTTYPE_OFFSET	28
 #define FSL_QDMA_CMD_LWC_OFFSET		16
 
+#define FSL_QDMA_CMD_SSEN		BIT(19)
+#define FSL_QDMA_CFG_SSS_OFFSET		12
+#define FSL_QDMA_CMD_SSS_STRIDE		128
+#define FSL_QDMA_CMD_SSS_DISTANCE	128
+
 #define QDMA_CCDF_STATUS		20
 #define QDMA_CCDF_OFFSET		20
 #define QDMA_CCDF_MASK			GENMASK(28, 20)