diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1113-drm-amdgpu-add-support-for-self-irq-on-Vega10-v2.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1113-drm-amdgpu-add-support-for-self-irq-on-Vega10-v2.patch | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1113-drm-amdgpu-add-support-for-self-irq-on-Vega10-v2.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1113-drm-amdgpu-add-support-for-self-irq-on-Vega10-v2.patch new file mode 100644 index 00000000..644b77da --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1113-drm-amdgpu-add-support-for-self-irq-on-Vega10-v2.patch @@ -0,0 +1,151 @@ +From af71911de5996b7921c2440b13493f345d42beb9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Wed, 26 Sep 2018 14:15:21 +0200 +Subject: [PATCH 1113/2940] drm/amdgpu: add support for self irq on Vega10 v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This finally enables processing of ring 1 & 2. + +v2: fix copy&paste error + +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> +--- + drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 80 ++++++++++++++++++++++++-- + 1 file changed, 74 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +index 7553d91d10e3..6d1f804277f8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c ++++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +@@ -270,7 +270,7 @@ static void vega10_ih_irq_disable(struct amdgpu_device *adev) + static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, + struct amdgpu_ih_ring *ih) + { +- u32 wptr, tmp; ++ u32 wptr, reg, tmp; + + wptr = le32_to_cpu(*ih->wptr_cpu); + +@@ -278,7 +278,17 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, + goto out; + + /* Double check that the overflow wasn't already cleared. */ +- wptr = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR)); ++ ++ if (ih == &adev->irq.ih) ++ reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR); ++ else if (ih == &adev->irq.ih1) ++ reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING1); ++ else if (ih == &adev->irq.ih2) ++ reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING2); ++ else ++ BUG(); ++ ++ wptr = RREG32_NO_KIQ(reg); + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) + goto out; + +@@ -294,9 +304,18 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, + wptr, ih->rptr, tmp); + ih->rptr = tmp; + +- tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL)); ++ if (ih == &adev->irq.ih) ++ reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL); ++ else if (ih == &adev->irq.ih1) ++ reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING1); ++ else if (ih == &adev->irq.ih2) ++ reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING2); ++ else ++ BUG(); ++ ++ tmp = RREG32_NO_KIQ(reg); + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); +- WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp); ++ WREG32_NO_KIQ(reg, tmp); + + out: + return (wptr & ih->ptr_mask); +@@ -359,9 +378,52 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev, + /* XXX check if swapping is necessary on BE */ + *ih->rptr_cpu = ih->rptr; + WDOORBELL32(ih->doorbell_index, ih->rptr); +- } else { ++ } else if (ih == &adev->irq.ih) { + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); ++ } else if (ih == &adev->irq.ih1) { ++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr); ++ } else if (ih == &adev->irq.ih2) { ++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr); ++ } ++} ++ ++/** ++ * vega10_ih_self_irq - dispatch work for ring 1 and 2 ++ * ++ * @adev: amdgpu_device pointer ++ * @source: irq source ++ * @entry: IV with WPTR update ++ * ++ * Update the WPTR from the IV and schedule work to handle the entries. ++ */ ++static int vega10_ih_self_irq(struct amdgpu_device *adev, ++ struct amdgpu_irq_src *source, ++ struct amdgpu_iv_entry *entry) ++{ ++ uint32_t wptr = cpu_to_le32(entry->src_data[0]); ++ ++ switch (entry->ring_id) { ++ case 1: ++ *adev->irq.ih1.wptr_cpu = wptr; ++ schedule_work(&adev->irq.ih1_work); ++ break; ++ case 2: ++ *adev->irq.ih2.wptr_cpu = wptr; ++ schedule_work(&adev->irq.ih2_work); ++ break; ++ default: break; + } ++ return 0; ++} ++ ++static const struct amdgpu_irq_src_funcs vega10_ih_self_irq_funcs = { ++ .process = vega10_ih_self_irq, ++}; ++ ++static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev) ++{ ++ adev->irq.self_irq.num_types = 0; ++ adev->irq.self_irq.funcs = &vega10_ih_self_irq_funcs; + } + + static int vega10_ih_early_init(void *handle) +@@ -369,13 +431,19 @@ static int vega10_ih_early_init(void *handle) + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + vega10_ih_set_interrupt_funcs(adev); ++ vega10_ih_set_self_irq_funcs(adev); + return 0; + } + + static int vega10_ih_sw_init(void *handle) + { +- int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; ++ int r; ++ ++ r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0, ++ &adev->irq.self_irq); ++ if (r) ++ return r; + + r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, true); + if (r) +-- +2.17.1 + |