mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-18 11:33:36 -04:00
drm/amdgpu: fix and cleanup gmc_v9_0_flush_gpu_tlb_pasid
Testing for reset is pointless since the reset can start right after the test. The same PASID can be used by more than one VMID, invalidate each of them. Move the KIQ and all the workaround handling into common GMC code. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
0c525aa406
commit
e7b90e99fa
@@ -32,6 +32,7 @@
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_gmc.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include "amdgpu_xgmi.h"
|
||||
|
||||
#include <drm/drm_drv.h>
|
||||
@@ -630,6 +631,65 @@ error_alloc:
|
||||
dev_err(adev->dev, "Error flushing GPU TLB using the SDMA (%d)!\n", r);
|
||||
}
|
||||
|
||||
int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
|
||||
uint32_t flush_type, bool all_hub,
|
||||
uint32_t inst)
|
||||
{
|
||||
u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT :
|
||||
adev->usec_timeout;
|
||||
struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst];
|
||||
unsigned int ndw;
|
||||
signed long r;
|
||||
uint32_t seq;
|
||||
|
||||
if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
|
||||
!down_read_trylock(&adev->reset_domain->sem)) {
|
||||
return adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
|
||||
flush_type,
|
||||
all_hub, inst);
|
||||
}
|
||||
|
||||
/* 2 dwords flush + 8 dwords fence */
|
||||
ndw = kiq->pmf->invalidate_tlbs_size + 8;
|
||||
|
||||
if (adev->gmc.flush_tlb_needs_extra_type_2)
|
||||
ndw += kiq->pmf->invalidate_tlbs_size;
|
||||
|
||||
if (adev->gmc.flush_tlb_needs_extra_type_0)
|
||||
ndw += kiq->pmf->invalidate_tlbs_size;
|
||||
|
||||
spin_lock(&adev->gfx.kiq[inst].ring_lock);
|
||||
amdgpu_ring_alloc(ring, ndw);
|
||||
if (adev->gmc.flush_tlb_needs_extra_type_2)
|
||||
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);
|
||||
|
||||
if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0)
|
||||
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub);
|
||||
|
||||
kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r) {
|
||||
amdgpu_ring_undo(ring);
|
||||
spin_unlock(&adev->gfx.kiq[inst].ring_lock);
|
||||
goto error_unlock_reset;
|
||||
}
|
||||
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock(&adev->gfx.kiq[inst].ring_lock);
|
||||
r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
|
||||
if (r < 1) {
|
||||
dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r);
|
||||
r = -ETIME;
|
||||
goto error_unlock_reset;
|
||||
}
|
||||
r = 0;
|
||||
|
||||
error_unlock_reset:
|
||||
up_read(&adev->reset_domain->sem);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gmc_tmz_set -- check and set if a device supports TMZ
|
||||
* @adev: amdgpu_device pointer
|
||||
|
||||
Reference in New Issue
Block a user