SDMA MQDs leave IB_ENABLE clear,
causing INDIRECT packets to be ignored.

Set IB_ENABLE while retaining SWITCH_INSIDE_IB.

Signed-off-by: Yongqiang Sun <[email protected]>
---
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c   | 10 ++++++++++
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c   | 10 ++++++++++
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c   |  7 ++++++-
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c | 14 +++++++++-----
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c    |  8 +++++++-
 5 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
index 4f8a8a1a6186..ee7076db300a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
@@ -396,6 +396,16 @@ static void update_mqd_sdma(struct mqd_manager *mm, void 
*mqd,
        m->sdma_queue_id = q->sdma_queue_id;
        m->sdmax_rlcx_dummy_reg = SDMA_RLC_DUMMY_DEFAULT;
 
+       /*
+        * IB_ENABLE makes this user queue execute SDMA indirect-buffer
+        * packets. SWITCH_INSIDE_IB allows a context switch in the middle
+        * of a long-running command, including one fetched from an IB, so
+        * one queue cannot starve the engine.
+        * sdmax_rlcx_ib_cntl is the SDMA_RLC0_IB_CNTL register.
+        */
+        m->sdmax_rlcx_ib_cntl |= SDMA0_RLC0_IB_CNTL__IB_ENABLE_MASK |
+        SDMA0_RLC0_IB_CNTL__SWITCH_INSIDE_IB_MASK;
+
        q->is_active = QUEUE_IS_ACTIVE(*q);
 }
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
index bf015dc5b868..4ed00e2d7bf4 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
@@ -478,6 +478,16 @@ static void update_mqd_sdma(struct mqd_manager *mm, void 
*mqd,
        m->sdma_queue_id = q->sdma_queue_id;
        m->sdmax_rlcx_dummy_reg = SDMA_RLC_DUMMY_DEFAULT;
 
+       /*
+        * IB_ENABLE makes this user queue execute SDMA indirect-buffer
+        * packets. SWITCH_INSIDE_IB allows a context switch in the middle
+        * of a long-running command, including one fetched from an IB, so
+        * one queue cannot starve the engine.
+        * sdmax_rlcx_ib_cntl is the SDMA_QUEUE0_IB_CNTL register.
+        */
+        m->sdmax_rlcx_ib_cntl |= SDMA0_QUEUE0_IB_CNTL__IB_ENABLE_MASK |
+        SDMA0_QUEUE0_IB_CNTL__SWITCH_INSIDE_IB_MASK;
+
        q->is_active = QUEUE_IS_ACTIVE(*q);
 }
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
index 6ea09b031caf..3f2234edb1fe 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
@@ -355,9 +355,14 @@ static void update_mqd_sdma(struct mqd_manager *mm, void 
*mqd,
 
        /* Allow context switch so we don't cross-process starve with a massive
        * command buffer of long-running SDMA commands
+       * IB_ENABLE makes this user queue execute SDMA indirect-buffer
+       * packets. SWITCH_INSIDE_IB allows a context switch in the middle
+       * of a long-running command, including one fetched from an IB, so
+       * one queue cannot starve the engine.
        * sdmax_rlcx_ib_cntl represent SDMA_QUEUE0_IB_CNTL register
        */
-       m->sdmax_rlcx_ib_cntl |= SDMA0_QUEUE0_IB_CNTL__SWITCH_INSIDE_IB_MASK;
+       m->sdmax_rlcx_ib_cntl |= SDMA0_QUEUE0_IB_CNTL__SWITCH_INSIDE_IB_MASK |
+                                       SDMA0_QUEUE0_IB_CNTL__IB_ENABLE_MASK;
 
        q->is_active = QUEUE_IS_ACTIVE(*q);
 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
index 2bbf5e63f615..e71467862436 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
@@ -457,11 +457,15 @@ static void update_mqd_sdma(struct mqd_manager *mm, void 
*mqd,
 
        m->sdmax_queuen_dummy_reg1 = 1;
 
-       /* Allow context switch so we don't cross-process starve with a massive
-       * command buffer of long-running SDMA commands
-       * sdmax_queuen_ib_cntl represent SDMA_QUEUE0_IB_CNTL register
-       */
-       m->sdmax_queuen_ib_cntl |= 
SDMA0_SDMA_QUEUE0_IB_CNTL__SWITCH_INSIDE_IB_MASK;
+       /*
+        * IB_ENABLE makes this user queue execute SDMA indirect-buffer
+        * packets. SWITCH_INSIDE_IB allows a context switch in the middle
+        * of a long-running command, including one fetched from an IB, so
+        * one queue cannot starve the engine.
+        * sdmax_queuen_ib_cntl is the SDMA_QUEUE0_IB_CNTL register.
+        */
+       m->sdmax_queuen_ib_cntl |= SDMA0_SDMA_QUEUE0_IB_CNTL__IB_ENABLE_MASK |
+                                
SDMA0_SDMA_QUEUE0_IB_CNTL__SWITCH_INSIDE_IB_MASK;
 
        q->is_active = QUEUE_IS_ACTIVE(*q);
 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
index 6e6bc1ec0b64..c21091745869 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
@@ -571,8 +571,14 @@ static void update_mqd_sdma(struct mqd_manager *mm, void 
*mqd,
        m->sdmax_rlcx_dummy_reg = SDMA_RLC_DUMMY_DEFAULT;
        /* Allow context switch so we don't cross-process starve with a massive
         * command buffer of long-running SDMA commands
+        * IB_ENABLE makes this user queue execute SDMA indirect-buffer
+        * packets. SWITCH_INSIDE_IB allows a context switch in the middle
+        * of a long-running command, including one fetched from an IB, so
+        * one queue cannot starve the engine.
+        * sdmax_rlcx_ib_cntl is the SDMA_GFX_IB_CNTL register.
         */
-       m->sdmax_rlcx_ib_cntl |= SDMA0_GFX_IB_CNTL__SWITCH_INSIDE_IB_MASK;
+       m->sdmax_rlcx_ib_cntl |= SDMA0_GFX_IB_CNTL__SWITCH_INSIDE_IB_MASK |
+                                       SDMA0_GFX_IB_CNTL__IB_ENABLE_MASK;
 
        q->is_active = QUEUE_IS_ACTIVE(*q);
 }
-- 
2.43.0

Reply via email to