Remove unnessary status read before every send.

Signed-off-by: Gagandeep Singh <g.si...@nxp.com>
---
 drivers/dma/dpaa/dpaa_qdma.c | 186 ++++++++++++++++++-----------------
 drivers/dma/dpaa/dpaa_qdma.h |   7 ++
 2 files changed, 101 insertions(+), 92 deletions(-)

diff --git a/drivers/dma/dpaa/dpaa_qdma.c b/drivers/dma/dpaa/dpaa_qdma.c
index 8e8426b88d..4022ad6469 100644
--- a/drivers/dma/dpaa/dpaa_qdma.c
+++ b/drivers/dma/dpaa/dpaa_qdma.c
@@ -248,7 +248,8 @@ fsl_qdma_free_queue_resources(struct fsl_qdma_queue *queue)
 }
 
 static struct
-fsl_qdma_queue *fsl_qdma_prep_status_queue(void)
+fsl_qdma_queue *fsl_qdma_prep_status_queue(struct fsl_qdma_engine *fsl_qdma,
+                                          u32 id)
 {
        struct fsl_qdma_queue *status_head;
        unsigned int status_size;
@@ -277,6 +278,8 @@ fsl_qdma_queue *fsl_qdma_prep_status_queue(void)
               sizeof(struct fsl_qdma_format));
        status_head->n_cq = status_size;
        status_head->virt_head = status_head->cq;
+       status_head->queue_base = fsl_qdma->block_base +
+               FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, id);
 
        return status_head;
 }
@@ -334,12 +337,9 @@ fsl_qdma_halt(struct fsl_qdma_engine *fsl_qdma)
 }
 
 static int
-fsl_qdma_queue_transfer_complete(struct fsl_qdma_engine *fsl_qdma,
-                                void *block, int id, const uint16_t nb_cpls,
+fsl_qdma_queue_transfer_complete(void *block, const uint16_t nb_cpls,
                                 enum rte_dma_status_code *status)
 {
-       struct fsl_qdma_queue *fsl_status = fsl_qdma->status[id];
-       struct fsl_qdma_format *status_addr;
        u32 reg;
        int count = 0;
 
@@ -348,16 +348,7 @@ fsl_qdma_queue_transfer_complete(struct fsl_qdma_engine 
*fsl_qdma,
                if (reg & FSL_QDMA_BSQSR_QE_BE)
                        return count;
 
-               status_addr = fsl_status->virt_head;
-
-               reg = qdma_readl_be(block + FSL_QDMA_BSQMR);
-               reg |= FSL_QDMA_BSQMR_DI_BE;
-
-               qdma_desc_addr_set64(status_addr, 0x0);
-               fsl_status->virt_head++;
-               if (fsl_status->virt_head == fsl_status->cq + fsl_status->n_cq)
-                       fsl_status->virt_head = fsl_status->cq;
-               qdma_writel_be(reg, block + FSL_QDMA_BSQMR);
+               qdma_writel_be(FSL_QDMA_BSQMR_DI, block + FSL_QDMA_BSQMR);
                if (status != NULL)
                        status[count] = RTE_DMA_STATUS_SUCCESSFUL;
 
@@ -472,19 +463,37 @@ fsl_qdma_enqueue_desc(struct fsl_qdma_queue *fsl_queue,
 {
        void *block = fsl_queue->queue_base;
        struct fsl_qdma_format *csgf_src, *csgf_dest;
-       u32 reg;
 #ifdef RTE_DMA_DPAA_ERRATA_ERR050757
        struct fsl_qdma_sdf *sdf;
        u32 cfg = 0;
 #endif
 
+#ifdef CONFIG_RTE_DMA_DPAA_ERR_CHK
+       u32 reg;
+
        /* retrieve and store the register value in big endian
         * to avoid bits swap
         */
        reg = qdma_readl_be(block +
                         FSL_QDMA_BCQSR(fsl_queue->id));
-       if (reg & (FSL_QDMA_BCQSR_QF_XOFF_BE))
+       if (reg & (FSL_QDMA_BCQSR_QF_XOFF_BE)) {
+               DPAA_QDMA_ERR("QDMA Engine is busy\n");
                return -1;
+       }
+#else
+       /* check whether critical watermark level reached,
+        * below check is valid for only single queue per block
+        */
+       if ((fsl_queue->stats.submitted - fsl_queue->stats.completed)
+                       >= QDMA_QUEUE_CR_WM) {
+               DPAA_QDMA_DEBUG("Queue is full, try dequeue first\n");
+               return -1;
+       }
+#endif
+       if (unlikely(fsl_queue->pending == fsl_queue->n_cq)) {
+               DPAA_QDMA_DEBUG("Queue is full, try dma submit first\n");
+               return -1;
+       }
 
        csgf_src = (struct fsl_qdma_format 
*)fsl_queue->virt_addr[fsl_queue->ci] +
                   QDMA_SGF_SRC_OFF;
@@ -512,19 +521,14 @@ fsl_qdma_enqueue_desc(struct fsl_qdma_queue *fsl_queue,
        qdma_csgf_set_len(csgf_dest, len);
        /* This entry is the last entry. */
        qdma_csgf_set_f(csgf_dest, len);
-       fsl_queue->virt_head++;
        fsl_queue->ci++;
 
-       if (fsl_queue->virt_head == fsl_queue->cq + fsl_queue->n_cq) {
-               fsl_queue->virt_head = fsl_queue->cq;
+       if (fsl_queue->ci == fsl_queue->n_cq)
                fsl_queue->ci = 0;
-       }
-
 
        if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
-               reg = qdma_readl_be(block + FSL_QDMA_BCQMR(fsl_queue->id));
-               reg |= FSL_QDMA_BCQMR_EI_BE;
-               qdma_writel_be(reg, block + FSL_QDMA_BCQMR(fsl_queue->id));
+               qdma_writel_be(FSL_QDMA_BCQMR_EI,
+                              block + FSL_QDMA_BCQMR(fsl_queue->id));
                fsl_queue->stats.submitted++;
        } else {
                fsl_queue->pending++;
@@ -618,12 +622,9 @@ dpaa_qdma_submit(void *dev_private, uint16_t vchan)
        struct fsl_qdma_queue *fsl_queue =
                fsl_qdma->queue[fsl_qdma->vchan_map[vchan]];
        void *block = fsl_queue->queue_base;
-       u32 reg;
 
        while (fsl_queue->pending) {
-               reg = qdma_readl_be(block + FSL_QDMA_BCQMR(fsl_queue->id));
-               reg |= FSL_QDMA_BCQMR_EI_BE;
-               qdma_writel_be(reg, block + FSL_QDMA_BCQMR(fsl_queue->id));
+               qdma_writel_be(FSL_QDMA_BCQMR_EI, block + 
FSL_QDMA_BCQMR(fsl_queue->id));
                fsl_queue->pending--;
                fsl_queue->stats.submitted++;
        }
@@ -656,44 +657,43 @@ dpaa_qdma_dequeue_status(void *dev_private, uint16_t 
vchan,
                         enum rte_dma_status_code *st)
 {
        struct fsl_qdma_engine *fsl_qdma = (struct fsl_qdma_engine 
*)dev_private;
-       int id = (int)((fsl_qdma->vchan_map[vchan]) / QDMA_QUEUES);
-       void *block;
-       int intr;
-       void *status = fsl_qdma->status_base;
+       int ret;
        struct fsl_qdma_queue *fsl_queue =
                fsl_qdma->queue[fsl_qdma->vchan_map[vchan]];
+       void *status = fsl_qdma->status_base;
+       int intr;
 
-       intr = qdma_readl_be(status + FSL_QDMA_DEDR);
-       if (intr) {
-               DPAA_QDMA_ERR("DMA transaction error! %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFDW0R);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW0R %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFDW1R);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW1R %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFDW2R);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW2R %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFDW3R);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW3R %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFQIDR);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFQIDR %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECBR);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECBR %x\n", intr);
-               qdma_writel(0xffffffff,
-                           status + FSL_QDMA_DEDR);
-               intr = qdma_readl(status + FSL_QDMA_DEDR);
-               fsl_queue->stats.errors++;
+       ret = fsl_qdma_queue_transfer_complete(fsl_queue->queue_base,
+                                              nb_cpls, st);
+       if (!ret) {
+               intr = qdma_readl_be(status + FSL_QDMA_DEDR);
+               if (intr) {
+#ifdef CONFIG_RTE_DMA_DPAA_ERR_CHK
+                       DPAA_QDMA_ERR("DMA transaction error! %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFDW0R);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW0R %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFDW1R);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW1R %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFDW2R);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW2R %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFDW3R);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW3R %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFQIDR);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFQIDR %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECBR);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECBR %x\n", intr);
+#endif
+                       qdma_writel_be(0xbf,
+                                   status + FSL_QDMA_DEDR);
+                       fsl_queue->stats.errors++;
+               }
        }
 
-       block = fsl_qdma->block_base +
-               FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, id);
-
-       intr = fsl_qdma_queue_transfer_complete(fsl_qdma, block, id, nb_cpls,
-                                               st);
-       fsl_queue->stats.completed += intr;
+       fsl_queue->stats.completed += ret;
        if (last_idx != NULL)
                *last_idx = (uint16_t)(fsl_queue->stats.completed - 1);
 
-       return intr;
+       return ret;
 }
 
 
@@ -703,44 +703,46 @@ dpaa_qdma_dequeue(void *dev_private,
                  uint16_t *last_idx, bool *has_error)
 {
        struct fsl_qdma_engine *fsl_qdma = (struct fsl_qdma_engine 
*)dev_private;
-       int id = (int)((fsl_qdma->vchan_map[vchan]) / QDMA_QUEUES);
-       void *block;
-       int intr;
-       void *status = fsl_qdma->status_base;
+       int ret;
        struct fsl_qdma_queue *fsl_queue =
                fsl_qdma->queue[fsl_qdma->vchan_map[vchan]];
+#ifdef CONFIG_RTE_DMA_DPAA_ERR_CHK
+       void *status = fsl_qdma->status_base;
+       int intr;
+#endif
 
-       intr = qdma_readl_be(status + FSL_QDMA_DEDR);
-       if (intr) {
-               DPAA_QDMA_ERR("DMA transaction error! %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFDW0R);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW0R %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFDW1R);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW1R %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFDW2R);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW2R %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFDW3R);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW3R %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECFQIDR);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECFQIDR %x\n", intr);
-               intr = qdma_readl(status + FSL_QDMA_DECBR);
-               DPAA_QDMA_INFO("reg FSL_QDMA_DECBR %x\n", intr);
-               qdma_writel(0xffffffff,
-                           status + FSL_QDMA_DEDR);
-               intr = qdma_readl(status + FSL_QDMA_DEDR);
-               *has_error = true;
-               fsl_queue->stats.errors++;
+       *has_error = false;
+       ret = fsl_qdma_queue_transfer_complete(fsl_queue->queue_base,
+                                              nb_cpls, NULL);
+#ifdef CONFIG_RTE_DMA_DPAA_ERR_CHK
+       if (!ret) {
+               intr = qdma_readl_be(status + FSL_QDMA_DEDR);
+               if (intr) {
+                       DPAA_QDMA_ERR("DMA transaction error! %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFDW0R);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW0R %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFDW1R);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW1R %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFDW2R);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW2R %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFDW3R);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFDW3R %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECFQIDR);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECFQIDR %x\n", intr);
+                       intr = qdma_readl(status + FSL_QDMA_DECBR);
+                       DPAA_QDMA_INFO("reg FSL_QDMA_DECBR %x\n", intr);
+                       qdma_writel_be(0xbf,
+                                   status + FSL_QDMA_DEDR);
+                       intr = qdma_readl(status + FSL_QDMA_DEDR);
+                       *has_error = true;
+                       fsl_queue->stats.errors++;
+               }
        }
-
-       block = fsl_qdma->block_base +
-               FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, id);
-
-       intr = fsl_qdma_queue_transfer_complete(fsl_qdma, block, id, nb_cpls,
-                                               NULL);
-       fsl_queue->stats.completed += intr;
+#endif
+       fsl_queue->stats.completed += ret;
        if (last_idx != NULL)
                *last_idx = (uint16_t)(fsl_queue->stats.completed - 1);
-       return intr;
+       return ret;
 }
 
 static int
@@ -842,7 +844,7 @@ dpaa_qdma_init(struct rte_dma_dev *dmadev)
        }
 
        for (i = 0; i < fsl_qdma->num_blocks; i++) {
-               fsl_qdma->status[i] = fsl_qdma_prep_status_queue();
+               fsl_qdma->status[i] = fsl_qdma_prep_status_queue(fsl_qdma, i);
                if (!fsl_qdma->status[i])
                        goto mem_free;
                j = 0;
diff --git a/drivers/dma/dpaa/dpaa_qdma.h b/drivers/dma/dpaa/dpaa_qdma.h
index 80366ce890..8a4517a70a 100644
--- a/drivers/dma/dpaa/dpaa_qdma.h
+++ b/drivers/dma/dpaa/dpaa_qdma.h
@@ -58,11 +58,17 @@
 #define FSL_QDMA_BCQMR_CD_THLD(x)      ((x) << 20)
 #define FSL_QDMA_BCQMR_CQ_SIZE(x)      ((x) << 16)
 
+/* Update the value appropriately whenever QDMA_QUEUE_SIZE
+ * changes.
+ */
+#define FSL_QDMA_BCQMR_EI              0x20c0
+
 #define FSL_QDMA_BCQSR_QF_XOFF_BE      0x1000100
 
 #define FSL_QDMA_BSQMR_EN              0x80000000
 #define FSL_QDMA_BSQMR_DI_BE           0x40
 #define FSL_QDMA_BSQMR_CQ_SIZE(x)      ((x) << 16)
+#define FSL_QDMA_BSQMR_DI              0xc0
 
 #define FSL_QDMA_BSQSR_QE_BE           0x200
 
@@ -110,6 +116,7 @@
 #define QDMA_SGF_SRC_OFF               2
 #define QDMA_SGF_DST_OFF               3
 #define QDMA_DESC_OFF                  1
+#define QDMA_QUEUE_CR_WM               32
 
 #define QDMA_BIG_ENDIAN                        1
 #ifdef QDMA_BIG_ENDIAN
-- 
2.25.1

Reply via email to