On Tue, Jul 14, 2026 at 5:41 AM Christian König <[email protected]> wrote: > > On 7/13/26 20:27, Alex Deucher wrote: > > Adds a new helper to do TLB invalidation using SDMA. > > We already have that. See function amdgpu_gmc_flush_gpu_tlb().
This is a helper for the gmc IP components to replace their gmc specific callbacks that are used internally by amdgpu_gmc_flush_gpu_tlb(). See the last 3 patches in the series. This cleans up a lot of duplicated code in gmc10/11/12 and also replaces the use of MES for tlb invalidation with SDMA. Alex > > Regards, > Christian. > > > > > Signed-off-by: Alex Deucher <[email protected]> > > --- > > drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 36 +++++++++++++++++++++ > > drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 2 ++ > > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 42 +++++++++++++++++++++++++ > > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 6 ++++ > > 4 files changed, 86 insertions(+) > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > > index 3f0b1b7a557b9..5c1237a30b865 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > > @@ -928,6 +928,42 @@ void amdgpu_gmc_fw_reg_write_reg_wait(struct > > amdgpu_device *adev, > > dev_err(adev->dev, "failed to write reg %x wait reg %x\n", reg0, > > reg1); > > } > > > > +int amdgpu_gmc_flush_gpu_tlb_helper(struct amdgpu_device *adev, uint32_t > > vmid, > > + uint32_t vmhub, uint32_t flush_type) > > +{ > > + struct dma_fence *fence; > > + /* Use register 17 for GART */ > > + u32 inst, eng = 17; > > + int r; > > + > > + if (AMDGPU_IS_GFXHUB(vmhub) && !adev->gfx.is_poweron) > > + return 0; > > + > > + if (vmhub >= AMDGPU_MMHUB0(0)) > > + inst = 0; > > + else > > + inst = vmhub; > > + > > + /* flush hdp cache */ > > + amdgpu_device_flush_hdp(adev, NULL); > > + > > + mutex_lock(&adev->mman.default_entity.lock); > > + r = amdgpu_ttm_tlb_inv(adev, vmid, vmhub, eng, flush_type, inst, > > + &adev->mman.default_entity, > > + NULL, &fence); > > + if (r) > > + goto exit; > > + r = dma_fence_wait(fence, false); > > + dma_fence_put(fence); > > + if (r) > > + goto exit; > > + > > +exit: > > + mutex_unlock(&adev->mman.default_entity.lock); > > + > > + return r; > > +} > > + > > /** > > * 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 3ca187f5ade85..0135be1418a91 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h > > @@ -450,6 +450,8 @@ 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); > > +int amdgpu_gmc_flush_gpu_tlb_helper(struct amdgpu_device *adev, uint32_t > > vmid, > > + uint32_t vmhub, uint32_t flush_type); > > > > 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_ttm.c > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > > index 74ada995bd8e5..03e74b7ca0003 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > > @@ -2513,6 +2513,48 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev, > > return r; > > } > > > > +int amdgpu_ttm_tlb_inv(struct amdgpu_device *adev, > > + unsigned int vmid, u32 vmhub, u32 eng, > > + u32 flush_type, u32 xcc_inst, > > + struct amdgpu_ttm_buffer_entity *entity, > > + struct dma_resv *resv, > > + struct dma_fence **fence) > > +{ > > + struct amdgpu_ring *ring; > > + struct amdgpu_job *job; > > + int r, num_dw; > > + > > + if (!adev->mman.buffer_funcs_enabled) > > + return -EINVAL; > > + > > + ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]); > > + > > + if (!ring->sched.ready) { > > + dev_err(adev->dev, > > + "Trying to inv tlbs with ring turned off.\n"); > > + return -EINVAL; > > + } > > + > > + num_dw = ALIGN(adev->mman.buffer_funcs->tlb_inv_num_dw, 8); > > + r = amdgpu_ttm_prepare_job(adev, entity, num_dw, > > + resv, false, &job, > > + AMDGPU_KERNEL_JOB_ID_VM_UPDATE); > > + if (r) > > + goto error_free; > > + > > + amdgpu_emit_tlb_inv(adev, &job->ibs[0], vmid, vmhub, eng, > > + flush_type, xcc_inst); > > + > > + *fence = amdgpu_ttm_job_submit(adev, entity, job, num_dw); > > + > > + return 0; > > + > > +error_free: > > + amdgpu_job_free(job); > > + dev_err(adev->dev, "Error scheduling IBs (%d)\n", r); > > + return r; > > +} > > + > > static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev, > > struct amdgpu_ttm_buffer_entity *entity, > > uint32_t src_data, > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > > index ff9e2e3466099..f6a69c5a5ee86 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > > @@ -195,6 +195,12 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev, > > struct dma_resv *resv, > > struct dma_fence **fence, > > bool vm_needs_flush, uint32_t copy_flags); > > +int amdgpu_ttm_tlb_inv(struct amdgpu_device *adev, > > + unsigned int vmid, u32 vmhub, u32 eng, > > + u32 flush_type, u32 xcc_inst, > > + struct amdgpu_ttm_buffer_entity *entity, > > + struct dma_resv *resv, > > + struct dma_fence **fence); > > int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity, > > struct amdgpu_bo *bo, > > struct dma_resv *resv, >
