From: Jun Yang <jun.y...@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.y...@nxp.com>
Signed-off-by: Gagandeep Singh <g.si...@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

Reply via email to