diff options
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.patch | 194 |
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 + |