accel/habanalabs: fix register address on PDMA/EDMA idle check
authorKoby Elbaz <kelbaz@habana.ai>
Tue, 21 Feb 2023 12:21:39 +0000 (14:21 +0200)
committerOded Gabbay <ogabbay@kernel.org>
Wed, 15 Mar 2023 11:29:15 +0000 (13:29 +0200)
The PDMA/EDMA is_idle routines didn't check the correct CORE register
in order to get the accurate idle state.
Moreover, it's better to make the is_idle routine more robust by adding
additional checks (IS_HALTED) before announcing that the core is idle.

Signed-off-by: Koby Elbaz <kelbaz@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
drivers/accel/habanalabs/gaudi2/gaudi2.c

index 210c404..9057cb0 100644 (file)
 
 #define KDMA_TIMEOUT_USEC                      USEC_PER_SEC
 
-#define IS_DMA_IDLE(dma_core_idle_ind_mask)    \
-       (!((dma_core_idle_ind_mask) &           \
-       ((DCORE0_EDMA0_CORE_IDLE_IND_MASK_DESC_CNT_STS_MASK) | \
-       (DCORE0_EDMA0_CORE_IDLE_IND_MASK_COMP_MASK))))
+#define IS_DMA_IDLE(dma_core_sts0)     \
+       (!((dma_core_sts0) & (DCORE0_EDMA0_CORE_STS0_BUSY_MASK)))
+
+#define IS_DMA_HALTED(dma_core_sts1)   \
+       ((dma_core_sts1) & (DCORE0_EDMA0_CORE_STS1_IS_HALT_MASK))
 
 #define IS_MME_IDLE(mme_arch_sts) (((mme_arch_sts) & MME_ARCH_IDLE_MASK) == MME_ARCH_IDLE_MASK)
 
@@ -6677,18 +6678,18 @@ static int gaudi2_compute_reset_late_init(struct hl_device *hdev)
 static bool gaudi2_get_edma_idle_status(struct hl_device *hdev, u64 *mask_arr, u8 mask_len,
                struct engines_data *e)
 {
-       u32 qm_glbl_sts0, qm_glbl_sts1, qm_cgm_sts, dma_core_idle_ind_mask;
+       u32 qm_glbl_sts0, qm_glbl_sts1, qm_cgm_sts, dma_core_sts0, dma_core_sts1;
        struct asic_fixed_properties *prop = &hdev->asic_prop;
        unsigned long *mask = (unsigned long *) mask_arr;
-       const char *edma_fmt = "%-6d%-6d%-9s%#-14x%#x\n";
+       const char *edma_fmt = "%-6d%-6d%-9s%#-14x%#-15x%#x\n";
        bool is_idle = true, is_eng_idle;
        int engine_idx, i, j;
        u64 offset;
 
        if (e)
                hl_engine_data_sprintf(e,
-                       "\nCORE  EDMA  is_idle  QM_GLBL_STS0  DMA_CORE_IDLE_IND_MASK\n"
-                       "----  ----  -------  ------------  ----------------------\n");
+                       "\nCORE  EDMA  is_idle  QM_GLBL_STS0  DMA_CORE_STS0  DMA_CORE_STS1\n"
+                       "----  ----  -------  ------------  -------------  -------------\n");
 
        for (i = 0; i < NUM_OF_DCORES; i++) {
                for (j = 0 ; j < NUM_OF_EDMA_PER_DCORE ; j++) {
@@ -6701,25 +6702,23 @@ static bool gaudi2_get_edma_idle_status(struct hl_device *hdev, u64 *mask_arr, u
                                        i * GAUDI2_ENGINE_ID_DCORE_OFFSET + j;
                        offset = i * DCORE_OFFSET + j * DCORE_EDMA_OFFSET;
 
-                       dma_core_idle_ind_mask =
-                       RREG32(mmDCORE0_EDMA0_CORE_IDLE_IND_MASK + offset);
+                       dma_core_sts0 = RREG32(mmDCORE0_EDMA0_CORE_STS0 + offset);
+                       dma_core_sts1 = RREG32(mmDCORE0_EDMA0_CORE_STS1 + offset);
 
                        qm_glbl_sts0 = RREG32(mmDCORE0_EDMA0_QM_GLBL_STS0 + offset);
                        qm_glbl_sts1 = RREG32(mmDCORE0_EDMA0_QM_GLBL_STS1 + offset);
                        qm_cgm_sts = RREG32(mmDCORE0_EDMA0_QM_CGM_STS + offset);
 
                        is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_glbl_sts1, qm_cgm_sts) &&
-                                       IS_DMA_IDLE(dma_core_idle_ind_mask);
+                                       IS_DMA_IDLE(dma_core_sts0) && !IS_DMA_HALTED(dma_core_sts1);
                        is_idle &= is_eng_idle;
 
                        if (mask && !is_eng_idle)
                                set_bit(engine_idx, mask);
 
                        if (e)
-                               hl_engine_data_sprintf(e, edma_fmt, i, j,
-                                                       is_eng_idle ? "Y" : "N",
-                                                       qm_glbl_sts0,
-                                                       dma_core_idle_ind_mask);
+                               hl_engine_data_sprintf(e, edma_fmt, i, j, is_eng_idle ? "Y" : "N",
+                                                       qm_glbl_sts0, dma_core_sts0, dma_core_sts1);
                }
        }
 
@@ -6729,29 +6728,30 @@ static bool gaudi2_get_edma_idle_status(struct hl_device *hdev, u64 *mask_arr, u
 static bool gaudi2_get_pdma_idle_status(struct hl_device *hdev, u64 *mask_arr, u8 mask_len,
                struct engines_data *e)
 {
-       u32 qm_glbl_sts0, qm_glbl_sts1, qm_cgm_sts, dma_core_idle_ind_mask;
+       u32 qm_glbl_sts0, qm_glbl_sts1, qm_cgm_sts, dma_core_sts0, dma_core_sts1;
        unsigned long *mask = (unsigned long *) mask_arr;
-       const char *pdma_fmt = "%-6d%-9s%#-14x%#x\n";
+       const char *pdma_fmt = "%-6d%-9s%#-14x%#-15x%#x\n";
        bool is_idle = true, is_eng_idle;
        int engine_idx, i;
        u64 offset;
 
        if (e)
                hl_engine_data_sprintf(e,
-                                       "\nPDMA  is_idle  QM_GLBL_STS0  DMA_CORE_IDLE_IND_MASK\n"
-                                       "----  -------  ------------  ----------------------\n");
+                                       "\nPDMA  is_idle  QM_GLBL_STS0  DMA_CORE_STS0  DMA_CORE_STS1\n"
+                                       "----  -------  ------------  -------------  -------------\n");
 
        for (i = 0 ; i < NUM_OF_PDMA ; i++) {
                engine_idx = GAUDI2_ENGINE_ID_PDMA_0 + i;
                offset = i * PDMA_OFFSET;
-               dma_core_idle_ind_mask = RREG32(mmPDMA0_CORE_IDLE_IND_MASK + offset);
+               dma_core_sts0 = RREG32(mmPDMA0_CORE_STS0 + offset);
+               dma_core_sts1 = RREG32(mmPDMA0_CORE_STS1 + offset);
 
                qm_glbl_sts0 = RREG32(mmPDMA0_QM_GLBL_STS0 + offset);
                qm_glbl_sts1 = RREG32(mmPDMA0_QM_GLBL_STS1 + offset);
                qm_cgm_sts = RREG32(mmPDMA0_QM_CGM_STS + offset);
 
                is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_glbl_sts1, qm_cgm_sts) &&
-                               IS_DMA_IDLE(dma_core_idle_ind_mask);
+                               IS_DMA_IDLE(dma_core_sts0) && !IS_DMA_HALTED(dma_core_sts1);
                is_idle &= is_eng_idle;
 
                if (mask && !is_eng_idle)
@@ -6759,7 +6759,7 @@ static bool gaudi2_get_pdma_idle_status(struct hl_device *hdev, u64 *mask_arr, u
 
                if (e)
                        hl_engine_data_sprintf(e, pdma_fmt, i, is_eng_idle ? "Y" : "N",
-                                               qm_glbl_sts0, dma_core_idle_ind_mask);
+                                               qm_glbl_sts0, dma_core_sts0, dma_core_sts1);
        }
 
        return is_idle;