aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/5657-drm-amdkfd-Align-CIK-interrupt-processing-with-upstr.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/5657-drm-amdkfd-Align-CIK-interrupt-processing-with-upstr.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/5657-drm-amdkfd-Align-CIK-interrupt-processing-with-upstr.patch194
1 files changed, 194 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/5657-drm-amdkfd-Align-CIK-interrupt-processing-with-upstr.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/5657-drm-amdkfd-Align-CIK-interrupt-processing-with-upstr.patch
new file mode 100644
index 00000000..f9324020
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/5657-drm-amdkfd-Align-CIK-interrupt-processing-with-upstr.patch
@@ -0,0 +1,194 @@
+From dc143f18f00607ab184654bf48c60456587ce209 Mon Sep 17 00:00:00 2001
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+Date: Mon, 23 Apr 2018 21:59:05 -0400
+Subject: [PATCH 5657/5725] drm/amdkfd: Align CIK interrupt processing with
+ upstream
+
+Remove bitfields from struct cik_ih_ring_entry and use shiftr and
+masks instead. Reorder the INTSRC definitions to match upstream.
+Minor clean-up and simplification of VM-fault related code that
+hasn't been upstreamed yet.
+
+Change-Id: I23ded8d8b3b2731bf28517bb84023fa8d1d893cf
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+---
+ drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c | 73 +++++++++++++-----------
+ drivers/gpu/drm/amd/amdkfd/cik_int.h | 25 ++------
+ 2 files changed, 46 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
+index 751c004..1261432 100644
+--- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
++++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
+@@ -24,18 +24,13 @@
+ #include "kfd_events.h"
+ #include "cik_int.h"
+
+-static bool is_cpc_vm_fault(struct kfd_dev *dev,
+- const uint32_t *ih_ring_entry)
++static bool is_cpc_vm_fault(struct kfd_dev *dev, uint32_t source_id,
++ unsigned int vmid)
+ {
+- const struct cik_ih_ring_entry *ihre =
+- (const struct cik_ih_ring_entry *)ih_ring_entry;
+-
+- if ((ihre->source_id == CIK_INTSRC_GFX_PAGE_INV_FAULT ||
+- ihre->source_id == CIK_INTSRC_GFX_MEM_PROT_FAULT) &&
+- ihre->vmid >= dev->vm_info.first_vmid_kfd &&
+- ihre->vmid <= dev->vm_info.last_vmid_kfd)
+- return true;
+- return false;
++ return (source_id == CIK_INTSRC_GFX_PAGE_INV_FAULT ||
++ source_id == CIK_INTSRC_GFX_MEM_PROT_FAULT) &&
++ vmid >= dev->vm_info.first_vmid_kfd &&
++ vmid <= dev->vm_info.last_vmid_kfd;
+ }
+
+ static bool cik_event_interrupt_isr(struct kfd_dev *dev,
+@@ -46,8 +41,7 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev,
+ const struct cik_ih_ring_entry *ihre =
+ (const struct cik_ih_ring_entry *)ih_ring_entry;
+ const struct kfd2kgd_calls *f2g = dev->kfd2kgd;
+- struct cik_ih_ring_entry *tmp_ihre =
+- (struct cik_ih_ring_entry *) patched_ihre;
++ unsigned int vmid, pasid;
+
+ /* This workaround is due to HW/FW limitation on Hawaii that
+ * VMID and PASID are not written into ih_ring_entry
+@@ -55,23 +49,34 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev,
+ if ((ihre->source_id == CIK_INTSRC_GFX_PAGE_INV_FAULT ||
+ ihre->source_id == CIK_INTSRC_GFX_MEM_PROT_FAULT) &&
+ dev->device_info->asic_family == CHIP_HAWAII) {
++ struct cik_ih_ring_entry *tmp_ihre =
++ (struct cik_ih_ring_entry *)patched_ihre;
++
+ *patched_flag = true;
+ *tmp_ihre = *ihre;
+
+- tmp_ihre->vmid = f2g->read_vmid_from_vmfault_reg(dev->kgd);
+- tmp_ihre->pasid = f2g->get_atc_vmid_pasid_mapping_pasid(
+- dev->kgd, tmp_ihre->vmid);
+- return (tmp_ihre->pasid != 0) &&
+- tmp_ihre->vmid >= dev->vm_info.first_vmid_kfd &&
+- tmp_ihre->vmid <= dev->vm_info.last_vmid_kfd;
++ vmid = f2g->read_vmid_from_vmfault_reg(dev->kgd);
++ pasid = f2g->get_atc_vmid_pasid_mapping_pasid(dev->kgd, vmid);
++
++ tmp_ihre->ring_id &= 0x000000ff;
++ tmp_ihre->ring_id |= vmid << 8;
++ tmp_ihre->ring_id |= pasid << 16;
++
++ return (pasid != 0) &&
++ vmid >= dev->vm_info.first_vmid_kfd &&
++ vmid <= dev->vm_info.last_vmid_kfd;
+ }
++
++ vmid = (ihre->ring_id & 0x0000ff00) >> 8;
++ pasid = (ihre->ring_id & 0xffff0000) >> 16;
++
+ /* Do not process in ISR, just request it to be forwarded to WQ. */
+- return (ihre->pasid != 0) &&
++ return (pasid != 0) &&
+ (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE ||
+- ihre->source_id == CIK_INTSRC_SDMA_TRAP ||
+- ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG ||
+- ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE ||
+- is_cpc_vm_fault(dev, ih_ring_entry));
++ ihre->source_id == CIK_INTSRC_SDMA_TRAP ||
++ ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG ||
++ ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE ||
++ is_cpc_vm_fault(dev, ihre->source_id, vmid));
+ }
+
+ static void cik_event_interrupt_wq(struct kfd_dev *dev,
+@@ -80,33 +85,35 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev,
+ const struct cik_ih_ring_entry *ihre =
+ (const struct cik_ih_ring_entry *)ih_ring_entry;
+ uint32_t context_id = ihre->data & 0xfffffff;
++ unsigned int vmid = (ihre->ring_id & 0x0000ff00) >> 8;
++ unsigned int pasid = (ihre->ring_id & 0xffff0000) >> 16;
+
+- if (ihre->pasid == 0)
++ if (pasid == 0)
+ return;
+
+ if (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE)
+- kfd_signal_event_interrupt(ihre->pasid, context_id, 28);
++ kfd_signal_event_interrupt(pasid, context_id, 28);
+ else if (ihre->source_id == CIK_INTSRC_SDMA_TRAP)
+- kfd_signal_event_interrupt(ihre->pasid, context_id, 28);
++ kfd_signal_event_interrupt(pasid, context_id, 28);
+ else if (ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG)
+- kfd_signal_event_interrupt(ihre->pasid, context_id & 0xff, 8);
++ kfd_signal_event_interrupt(pasid, context_id & 0xff, 8);
+ else if (ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE)
+- kfd_signal_hw_exception_event(ihre->pasid);
++ kfd_signal_hw_exception_event(pasid);
+ else if (ihre->source_id == CIK_INTSRC_GFX_PAGE_INV_FAULT ||
+ ihre->source_id == CIK_INTSRC_GFX_MEM_PROT_FAULT) {
+ struct kfd_vm_fault_info info;
+
+- kfd_process_vm_fault(dev->dqm, ihre->pasid);
++ kfd_process_vm_fault(dev->dqm, pasid);
+
+ memset(&info, 0, sizeof(info));
+ dev->kfd2kgd->get_vm_fault_info(dev->kgd, &info);
+ if (!info.page_addr && !info.status)
+ return;
+
+- if (info.vmid == ihre->vmid)
+- kfd_signal_vm_fault_event(dev, ihre->pasid, &info);
++ if (info.vmid == vmid)
++ kfd_signal_vm_fault_event(dev, pasid, &info);
+ else
+- kfd_signal_vm_fault_event(dev, ihre->pasid, NULL);
++ kfd_signal_vm_fault_event(dev, pasid, NULL);
+ }
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/cik_int.h b/drivers/gpu/drm/amd/amdkfd/cik_int.h
+index ff8255d..a2079a0 100644
+--- a/drivers/gpu/drm/amd/amdkfd/cik_int.h
++++ b/drivers/gpu/drm/amd/amdkfd/cik_int.h
+@@ -26,32 +26,19 @@
+ #include <linux/types.h>
+
+ struct cik_ih_ring_entry {
+- uint32_t source_id:8;
+- uint32_t reserved1:8;
+- uint32_t reserved2:16;
+-
+- uint32_t data:28;
+- uint32_t reserved3:4;
+-
+- /* pipeid, meid and unused3 are officially called RINGID,
+- * but for our purposes, they always decode into pipe and ME.
+- */
+- uint32_t pipeid:2;
+- uint32_t meid:2;
+- uint32_t reserved4:4;
+- uint32_t vmid:8;
+- uint32_t pasid:16;
+-
+- uint32_t reserved5;
++ uint32_t source_id;
++ uint32_t data;
++ uint32_t ring_id;
++ uint32_t reserved;
+ };
+
+-#define CIK_INTSRC_DEQUEUE_COMPLETE 0xC6
+ #define CIK_INTSRC_CP_END_OF_PIPE 0xB5
+ #define CIK_INTSRC_CP_BAD_OPCODE 0xB7
++#define CIK_INTSRC_DEQUEUE_COMPLETE 0xC6
++#define CIK_INTSRC_SDMA_TRAP 0xE0
+ #define CIK_INTSRC_SQ_INTERRUPT_MSG 0xEF
+ #define CIK_INTSRC_GFX_PAGE_INV_FAULT 0x92
+ #define CIK_INTSRC_GFX_MEM_PROT_FAULT 0x93
+-#define CIK_INTSRC_SDMA_TRAP 0xE0
+
+ #endif
+
+--
+2.7.4
+