aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch270
1 files changed, 270 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1666-drm-amdgpu-Implement-new-invalidate-tlb-in-amdgpu.patch b/meta-amd-bsp/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/meta-amd-bsp/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
+