diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch new file mode 100644 index 00000000..968e4da9 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch @@ -0,0 +1,270 @@ +From d434b8d96d2f632607a78f46828186a98c37183d Mon Sep 17 00:00:00 2001 +From: Shaoyun Liu <Shaoyun.Liu@amd.com> +Date: Mon, 24 Apr 2017 10:57:54 -0400 +Subject: [PATCH 1666/4131] drm/amdgpu: Implement new invalidate tlb in amdgpu + +1. Add invalidate tlb interface in kfd2kgd. +2. Switch to use command package for tlb invalidation on asic newer than v8 + when kiq is enabled. + +Change-Id: Ia6c04ca7a3a57423cc1ab95c42d0787705957151 +Signed-off-by: Shaoyun Liu <Shaoyun.Liu@amd.com> + + Conflicts: + drivers/gpu/drm/amd/amdgpu/soc15d.h + drivers/gpu/drm/amd/amdgpu/vid.h +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 23 ++++++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 52 ++++++++++++++++++++++- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 51 ++++++++++++++++++++++ + drivers/gpu/drm/amd/amdgpu/vid.h | 4 ++ + drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 3 ++ + 5 files changed, 132 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +index 073a500..2abf945 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +@@ -144,6 +144,7 @@ static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid); + static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, + uint8_t vmid); + static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid); ++static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid); + static void set_num_of_requests(struct kgd_dev *dev, uint8_t num_of_req); + static int alloc_memory_of_scratch(struct kgd_dev *kgd, + uint64_t va, uint32_t vmid); +@@ -211,6 +212,7 @@ static const struct kfd2kgd_calls kfd2kgd = { + get_atc_vmid_pasid_mapping_valid, + .read_vmid_from_vmfault_reg = read_vmid_from_vmfault_reg, + .write_vmid_invalidate_request = write_vmid_invalidate_request, ++ .invalidate_tlbs = invalidate_tlbs, + .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu, + .free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu, + .map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu, +@@ -810,6 +812,27 @@ static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid) + WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); + } + ++static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *) kgd; ++ int vmid; ++ ++ for (vmid = 0; vmid < 16; vmid++) { ++ if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) ++ continue; ++ if (RREG32(mmATC_VMID0_PASID_MAPPING + vmid) & ++ ATC_VMID0_PASID_MAPPING__VALID_MASK) { ++ if ((RREG32(mmATC_VMID0_PASID_MAPPING + vmid) & ++ ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) { ++ WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); ++ break; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + static int write_config_static_mem(struct kgd_dev *kgd, bool swizzle_enable, + uint8_t element_size, uint8_t index_stride, uint8_t mtype) + { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +index d92dce7..452bebd 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +@@ -104,7 +104,6 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, + uint32_t queue_id); + static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, + unsigned int utimeout); +-static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid); + static int kgd_address_watch_disable(struct kgd_dev *kgd); + static int kgd_address_watch_execute(struct kgd_dev *kgd, + unsigned int watch_point_id, +@@ -131,6 +130,7 @@ static int write_config_static_mem(struct kgd_dev *kgd, bool swizzle_enable, + uint8_t element_size, uint8_t index_stride, uint8_t mtype); + static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, + uint32_t page_table_base); ++static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid); + + /* Because of REG_GET_FIELD() being used, we put this function in the + * asic specific file. +@@ -190,6 +190,7 @@ static const struct kfd2kgd_calls kfd2kgd = { + .get_atc_vmid_pasid_mapping_valid = + get_atc_vmid_pasid_mapping_valid, + .write_vmid_invalidate_request = write_vmid_invalidate_request, ++ .invalidate_tlbs = invalidate_tlbs, + .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu, + .free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu, + .map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu, +@@ -757,6 +758,55 @@ static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid) + WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); + } + ++static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid) ++{ ++ signed long r; ++ struct fence *f; ++ struct amdgpu_ring *ring = &adev->gfx.kiq.ring; ++ ++ mutex_lock(&adev->virt.lock_kiq); ++ amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/ ++ amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0)); ++ amdgpu_ring_write(ring, ++ PACKET3_INVALIDATE_TLBS_DST_SEL(1) | ++ PACKET3_INVALIDATE_TLBS_PASID(pasid)); ++ amdgpu_fence_emit(ring, &f); ++ amdgpu_ring_commit(ring); ++ mutex_unlock(&adev->virt.lock_kiq); ++ ++ r = fence_wait(f, false); ++ if (r) ++ DRM_ERROR("wait for kiq fence error: %ld.\n", r); ++ fence_put(f); ++ ++ return r; ++} ++ ++static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *) kgd; ++ int vmid; ++ struct amdgpu_ring *ring = &adev->gfx.kiq.ring; ++ ++ if (ring->ready) ++ return invalidate_tlbs_with_kiq(adev, pasid); ++ ++ for (vmid = 0; vmid < 16; vmid++) { ++ if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) ++ continue; ++ if (RREG32(mmATC_VMID0_PASID_MAPPING + vmid) & ++ ATC_VMID0_PASID_MAPPING__VALID_MASK) { ++ if ((RREG32(mmATC_VMID0_PASID_MAPPING + vmid) & ++ ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) { ++ WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); ++ break; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + static int kgd_address_watch_disable(struct kgd_dev *kgd) + { + struct amdgpu_device *adev = get_amdgpu_device(kgd); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +index 796dc44..a2fe8be 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +@@ -46,6 +46,7 @@ + #include "soc15_common.h" + #include "v9_structs.h" + #include "soc15.h" ++#include "soc15d.h" + + /* HACK: MMHUB and GC both have VM-related register with the same + * names but different offsets. Define the MMHUB register we need here +@@ -168,6 +169,7 @@ static int write_config_static_mem(struct kgd_dev *kgd, bool swizzle_enable, + uint8_t element_size, uint8_t index_stride, uint8_t mtype); + static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, + uint32_t page_table_base); ++static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid); + + /* Because of REG_GET_FIELD() being used, we put this function in the + * asic specific file. +@@ -234,6 +236,7 @@ static const struct kfd2kgd_calls kfd2kgd = { + .get_atc_vmid_pasid_mapping_valid = + get_atc_vmid_pasid_mapping_valid, + .write_vmid_invalidate_request = write_vmid_invalidate_request, ++ .invalidate_tlbs = invalidate_tlbs, + .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu, + .free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu, + .map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu, +@@ -933,6 +936,54 @@ static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid) + cpu_relax(); + } + ++static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid) ++{ ++ signed long r; ++ struct fence *f; ++ struct amdgpu_ring *ring = &adev->gfx.kiq.ring; ++ ++ mutex_lock(&adev->virt.lock_kiq); ++ amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/ ++ amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0)); ++ amdgpu_ring_write(ring, ++ PACKET3_INVALIDATE_TLBS_DST_SEL(1) | ++ PACKET3_INVALIDATE_TLBS_PASID(pasid)); ++ amdgpu_fence_emit(ring, &f); ++ amdgpu_ring_commit(ring); ++ mutex_unlock(&adev->virt.lock_kiq); ++ ++ r = fence_wait(f, false); ++ if (r) ++ DRM_ERROR("wait for kiq fence error: %ld.\n", r); ++ fence_put(f); ++ ++ return r; ++} ++ ++static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *) kgd; ++ int vmid; ++ struct amdgpu_ring *ring = &adev->gfx.kiq.ring; ++ ++ if (ring->ready) ++ return invalidate_tlbs_with_kiq(adev, pasid); ++ ++ for (vmid = 0; vmid < 16; vmid++) { ++ if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) ++ continue; ++ if (get_atc_vmid_pasid_mapping_valid(kgd, vmid)) { ++ if (get_atc_vmid_pasid_mapping_pasid(kgd, vmid) ++ == pasid) { ++ write_vmid_invalidate_request(kgd, vmid); ++ break; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + static int kgd_address_watch_disable(struct kgd_dev *kgd) + { + struct amdgpu_device *adev = get_amdgpu_device(kgd); +diff --git a/drivers/gpu/drm/amd/amdgpu/vid.h b/drivers/gpu/drm/amd/amdgpu/vid.h +index 9806900..d09592a 100755 +--- a/drivers/gpu/drm/amd/amdgpu/vid.h ++++ b/drivers/gpu/drm/amd/amdgpu/vid.h +@@ -369,6 +369,10 @@ + * x=0: tmz_begin + * x=1: tmz_end + */ ++#define PACKET3_INVALIDATE_TLBS 0x98 ++# define PACKET3_INVALIDATE_TLBS_DST_SEL(x) ((x) << 0) ++# define PACKET3_INVALIDATE_TLBS_PASID(x) ((x) << 5) ++ + #define PACKET3_SET_RESOURCES 0xA0 + /* 1. header + * 2. CONTROL +diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +index cff1ee6..132a801 100644 +--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h ++++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +@@ -335,6 +335,9 @@ struct kfd2kgd_calls { + uint32_t (*read_vmid_from_vmfault_reg)(struct kgd_dev *kgd); + void (*write_vmid_invalidate_request)(struct kgd_dev *kgd, + uint8_t vmid); ++ ++ int (*invalidate_tlbs)(struct kgd_dev *kgd, uint16_t pasid); ++ + int (*alloc_memory_of_gpu)(struct kgd_dev *kgd, uint64_t va, + uint64_t size, void *vm, + struct kgd_mem **mem, uint64_t *offset, +-- +2.7.4 + |