[PATCH] drm/amdgpu: move kiq_reg_write_reg_wait() out of amdgpu_virt.c
Christian König
christian.koenig at amd.com
Tue Jan 9 07:25:32 UTC 2024
Am 08.01.24 um 22:38 schrieb Alex Deucher:
> 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.
>
> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> Cc: Shaoyun.Liu at amd.com
> Cc: Christian.Koenig at amd.com
I'm wondering if having an amdgpu_kiq.c wouldn't be better, but for now
the patch is Acked-by: Christian König <Christian.koenig at amd.com>
Regards,
Christian.
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 53 ++++++++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 4 ++
> drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 53 ------------------------
> drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 4 --
> drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 9 ++--
> drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 9 ++--
> drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 12 +++---
> 7 files changed, 74 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index d2f273d77e59..331cf6384b12 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -746,6 +746,59 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
> 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
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> index e699d1ca8deb..17f40ea1104b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> @@ -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);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index 0dcff2889e25..f5c66e0038b5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -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.
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> index d4207e44141f..1b49c007ff62 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> @@ -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);
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> index 6c5185608854..db89d13bd80d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> @@ -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);
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> index c9c653cfc765..6c68135cac9f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> @@ -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);
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index f9039d64ff2d..9bff72356a37 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -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);
>
> /*
More information about the amd-gfx
mailing list