drm/amdgpu: move kiq_reg_write_reg_wait() out of amdgpu_virt.c
authorAlex Deucher <alexander.deucher@amd.com>
Thu, 14 Dec 2023 17:18:45 +0000 (12:18 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 15 Jan 2024 23:35:36 +0000 (18:35 -0500)
It's used for more than just SR-IOV now, so move it to
amdgpu_gmc.c and rename it to better match the functionality and
update the comments in the code paths to better document
when each path is used and why.  No functional change.

Reviewed-by: Shaoyun.liu <Shaoyun.liu@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: Shaoyun.Liu@amd.com
Cc: Christian.Koenig@amd.com
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index 55784a9f26c4c83b17008a766130c234df8ecbaf..103f8a8df6d875c6f9e4b7825c7fd41934635053 100644 (file)
@@ -746,6 +746,59 @@ error_unlock_reset:
        return r;
 }
 
+void amdgpu_gmc_fw_reg_write_reg_wait(struct amdgpu_device *adev,
+                                     uint32_t reg0, uint32_t reg1,
+                                     uint32_t ref, uint32_t mask,
+                                     uint32_t xcc_inst)
+{
+       struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_inst];
+       struct amdgpu_ring *ring = &kiq->ring;
+       signed long r, cnt = 0;
+       unsigned long flags;
+       uint32_t seq;
+
+       if (adev->mes.ring.sched.ready) {
+               amdgpu_mes_reg_write_reg_wait(adev, reg0, reg1,
+                                             ref, mask);
+               return;
+       }
+
+       spin_lock_irqsave(&kiq->ring_lock, flags);
+       amdgpu_ring_alloc(ring, 32);
+       amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1,
+                                           ref, mask);
+       r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
+       if (r)
+               goto failed_undo;
+
+       amdgpu_ring_commit(ring);
+       spin_unlock_irqrestore(&kiq->ring_lock, flags);
+
+       r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
+
+       /* don't wait anymore for IRQ context */
+       if (r < 1 && in_interrupt())
+               goto failed_kiq;
+
+       might_sleep();
+       while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
+
+               msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
+               r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
+       }
+
+       if (cnt > MAX_KIQ_REG_TRY)
+               goto failed_kiq;
+
+       return;
+
+failed_undo:
+       amdgpu_ring_undo(ring);
+       spin_unlock_irqrestore(&kiq->ring_lock, flags);
+failed_kiq:
+       dev_err(adev->dev, "failed to write reg %x wait reg %x\n", reg0, reg1);
+}
+
 /**
  * amdgpu_gmc_tmz_set -- check and set if a device supports TMZ
  * @adev: amdgpu_device pointer
index e699d1ca8debd3e1d49de46a844048e67b55f23a..17f40ea1104b00bcfd1596337a2848b9dc5ef210 100644 (file)
@@ -417,6 +417,10 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
 int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
                                   uint32_t flush_type, bool all_hub,
                                   uint32_t inst);
+void amdgpu_gmc_fw_reg_write_reg_wait(struct amdgpu_device *adev,
+                                     uint32_t reg0, uint32_t reg1,
+                                     uint32_t ref, uint32_t mask,
+                                     uint32_t xcc_inst);
 
 extern void amdgpu_gmc_tmz_set(struct amdgpu_device *adev);
 extern void amdgpu_gmc_noretry_set(struct amdgpu_device *adev);
index 0dcff2889e25d2b8883a39eaf9d09755bb1c2373..f5c66e0038b548f911ae3990ee72ecbace6af3e7 100644 (file)
@@ -71,59 +71,6 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev)
                amdgpu_num_kcq = 2;
 }
 
-void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
-                                       uint32_t reg0, uint32_t reg1,
-                                       uint32_t ref, uint32_t mask,
-                                       uint32_t xcc_inst)
-{
-       struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_inst];
-       struct amdgpu_ring *ring = &kiq->ring;
-       signed long r, cnt = 0;
-       unsigned long flags;
-       uint32_t seq;
-
-       if (adev->mes.ring.sched.ready) {
-               amdgpu_mes_reg_write_reg_wait(adev, reg0, reg1,
-                                             ref, mask);
-               return;
-       }
-
-       spin_lock_irqsave(&kiq->ring_lock, flags);
-       amdgpu_ring_alloc(ring, 32);
-       amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1,
-                                           ref, mask);
-       r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
-       if (r)
-               goto failed_undo;
-
-       amdgpu_ring_commit(ring);
-       spin_unlock_irqrestore(&kiq->ring_lock, flags);
-
-       r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
-
-       /* don't wait anymore for IRQ context */
-       if (r < 1 && in_interrupt())
-               goto failed_kiq;
-
-       might_sleep();
-       while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
-
-               msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
-               r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
-       }
-
-       if (cnt > MAX_KIQ_REG_TRY)
-               goto failed_kiq;
-
-       return;
-
-failed_undo:
-       amdgpu_ring_undo(ring);
-       spin_unlock_irqrestore(&kiq->ring_lock, flags);
-failed_kiq:
-       dev_err(adev->dev, "failed to write reg %x wait reg %x\n", reg0, reg1);
-}
-
 /**
  * amdgpu_virt_request_full_gpu() - request full gpu access
  * @adev:      amdgpu device.
index d4207e44141f185bbcd28e28d638b084fda09ec9..1b49c007ff62d4745bfeb3c8aee722f1f10bf6f6 100644 (file)
@@ -332,10 +332,6 @@ static inline bool is_virtual_machine(void)
        ((adev)->virt.gim_feature & AMDGIM_FEATURE_VCN_RB_DECOUPLE)
 bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
 void amdgpu_virt_init_setting(struct amdgpu_device *adev);
-void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
-                                       uint32_t reg0, uint32_t rreg1,
-                                       uint32_t ref, uint32_t mask,
-                                       uint32_t xcc_inst);
 int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
 int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
 int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
index 6c51856088546faed3c2e3d9376f8c23d54ba554..db89d13bd80db6dbe769b2d59fc736a4b51f63fb 100644 (file)
@@ -262,16 +262,17 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
        /* flush hdp cache */
        adev->hdp.funcs->flush_hdp(adev, NULL);
 
-       /* For SRIOV run time, driver shouldn't access the register through MMIO
-        * Directly use kiq to do the vm invalidation instead
+       /* This is necessary for SRIOV as well as for GFXOFF to function
+        * properly under bare metal
         */
        if (adev->gfx.kiq[0].ring.sched.ready && !adev->enable_mes &&
            (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
-               amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
-                               1 << vmid, GET_INST(GC, 0));
+               amdgpu_gmc_fw_reg_write_reg_wait(adev, req, ack, inv_req,
+                                                1 << vmid, GET_INST(GC, 0));
                return;
        }
 
+       /* This path is needed before KIQ/MES/GFXOFF are set up */
        hub_ip = (vmhub == AMDGPU_GFXHUB(0)) ? GC_HWIP : MMHUB_HWIP;
 
        spin_lock(&adev->gmc.invalidate_lock);
index c9c653cfc765b8b88e5ab1f77cefcbbce38ff79c..6c68135cac9f021f522089345043474882b00d1c 100644 (file)
@@ -223,16 +223,17 @@ static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
        /* flush hdp cache */
        adev->hdp.funcs->flush_hdp(adev, NULL);
 
-       /* For SRIOV run time, driver shouldn't access the register through MMIO
-        * Directly use kiq to do the vm invalidation instead
+       /* This is necessary for SRIOV as well as for GFXOFF to function
+        * properly under bare metal
         */
        if ((adev->gfx.kiq[0].ring.sched.ready || adev->mes.ring.sched.ready) &&
            (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
-               amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
-                               1 << vmid, GET_INST(GC, 0));
+               amdgpu_gmc_fw_reg_write_reg_wait(adev, req, ack, inv_req,
+                                                1 << vmid, GET_INST(GC, 0));
                return;
        }
 
+       /* This path is needed before KIQ/MES/GFXOFF are set up */
        hub_ip = (vmhub == AMDGPU_GFXHUB(0)) ? GC_HWIP : MMHUB_HWIP;
 
        spin_lock(&adev->gmc.invalidate_lock);
index f9039d64ff2d72804556daa16b8ed9632b08b307..9bff72356a3716a242de0091a47ab9ad8dc960d2 100644 (file)
@@ -829,23 +829,25 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
        req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
        ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
 
-       /* This is necessary for a HW workaround under SRIOV as well
-        * as GFXOFF under bare metal
-        */
        if (vmhub >= AMDGPU_MMHUB0(0))
                inst = GET_INST(GC, 0);
        else
                inst = vmhub;
+
+       /* This is necessary for SRIOV as well as for GFXOFF to function
+        * properly under bare metal
+        */
        if (adev->gfx.kiq[inst].ring.sched.ready &&
            (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
                uint32_t req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
                uint32_t ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
 
-               amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
-                                                  1 << vmid, inst);
+               amdgpu_gmc_fw_reg_write_reg_wait(adev, req, ack, inv_req,
+                                                1 << vmid, inst);
                return;
        }
 
+       /* This path is needed before KIQ/MES/GFXOFF are set up */
        spin_lock(&adev->gmc.invalidate_lock);
 
        /*