aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1111-drm-amdgpu-enable-IH-ring-1-and-ring-2-v4.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1111-drm-amdgpu-enable-IH-ring-1-and-ring-2-v4.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1111-drm-amdgpu-enable-IH-ring-1-and-ring-2-v4.patch249
1 files changed, 249 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1111-drm-amdgpu-enable-IH-ring-1-and-ring-2-v4.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1111-drm-amdgpu-enable-IH-ring-1-and-ring-2-v4.patch
new file mode 100644
index 00000000..d04889df
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1111-drm-amdgpu-enable-IH-ring-1-and-ring-2-v4.patch
@@ -0,0 +1,249 @@
+From 199322c6dca9031b2ea669506cb9144dd276e454 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Tue, 18 Sep 2018 14:51:35 +0200
+Subject: [PATCH 1111/2940] drm/amdgpu: enable IH ring 1 and ring 2 v4
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The entries are ignored for now, but it at least stops crashing the
+hardware when somebody tries to push something to the other IH rings.
+
+v2: limit ring size, add TODO comment
+v3: only program rings if they are actually allocated
+v4: limit the ring init to Vega10
+
+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/amdgpu_irq.h | 4 +-
+ drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 145 ++++++++++++++++++++----
+ 2 files changed, 123 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+index dce9affc3ca0..c9dc17469242 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+@@ -87,8 +87,8 @@ struct amdgpu_irq {
+ /* status, etc. */
+ bool msi_enabled; /* msi enabled */
+
+- /* interrupt ring */
+- struct amdgpu_ih_ring ih;
++ /* interrupt rings */
++ struct amdgpu_ih_ring ih, ih1, ih2;
+ const struct amdgpu_ih_funcs *ih_funcs;
+
+ /* gen irq stuff */
+diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+index 877b4a6d21f7..7553d91d10e3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
++++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+@@ -50,6 +50,22 @@ static void vega10_ih_enable_interrupts(struct amdgpu_device *adev)
+ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
+ WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
+ adev->irq.ih.enabled = true;
++
++ if (adev->irq.ih1.ring_size) {
++ ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
++ RB_ENABLE, 1);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
++ adev->irq.ih1.enabled = true;
++ }
++
++ if (adev->irq.ih2.ring_size) {
++ ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
++ RB_ENABLE, 1);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
++ adev->irq.ih2.enabled = true;
++ }
+ }
+
+ /**
+@@ -71,6 +87,53 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
+ WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
+ adev->irq.ih.enabled = false;
+ adev->irq.ih.rptr = 0;
++
++ if (adev->irq.ih1.ring_size) {
++ ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
++ RB_ENABLE, 0);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
++ /* set rptr, wptr to 0 */
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
++ adev->irq.ih1.enabled = false;
++ adev->irq.ih1.rptr = 0;
++ }
++
++ if (adev->irq.ih2.ring_size) {
++ ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
++ RB_ENABLE, 0);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
++ /* set rptr, wptr to 0 */
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
++ adev->irq.ih2.enabled = false;
++ adev->irq.ih2.rptr = 0;
++ }
++}
++
++static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
++{
++ int rb_bufsz = order_base_2(ih->ring_size / 4);
++
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
++ MC_SPACE, ih->use_bus_addr ? 1 : 4);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
++ WPTR_OVERFLOW_CLEAR, 1);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
++ WPTR_OVERFLOW_ENABLE, 1);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
++ /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register
++ * value is written to memory
++ */
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
++ WPTR_WRITEBACK_ENABLE, 1);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
++
++ return ih_rb_cntl;
+ }
+
+ /**
+@@ -86,9 +149,8 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
+ */
+ static int vega10_ih_irq_init(struct amdgpu_device *adev)
+ {
+- struct amdgpu_ih_ring *ih = &adev->irq.ih;
++ struct amdgpu_ih_ring *ih;
+ int ret = 0;
+- int rb_bufsz;
+ u32 ih_rb_cntl, ih_doorbell_rtpr;
+ u32 tmp;
+
+@@ -97,26 +159,15 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
+
+ adev->nbio_funcs->ih_control(adev);
+
+- ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
++ ih = &adev->irq.ih;
+ /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
+- WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
+- WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI,
+- (adev->irq.ih.gpu_addr >> 40) & 0xff);
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE,
+- ih->use_bus_addr ? 1 : 4);
+- rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
+- /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register value is written to memory */
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
+-
+- if (adev->irq.msi_enabled)
+- ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM, 1);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, ih->gpu_addr >> 8);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff);
+
++ ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
++ ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
++ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
++ !!adev->irq.msi_enabled);
+ WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
+
+ /* set the writeback address whether it's enabled or not */
+@@ -131,16 +182,49 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
+
+ ih_doorbell_rtpr = RREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR);
+ if (adev->irq.ih.use_doorbell) {
+- ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
+- OFFSET, adev->irq.ih.doorbell_index);
+- ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
++ ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
++ IH_DOORBELL_RPTR, OFFSET,
++ adev->irq.ih.doorbell_index);
++ ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
++ IH_DOORBELL_RPTR,
+ ENABLE, 1);
+ } else {
+- ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
++ ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
++ IH_DOORBELL_RPTR,
+ ENABLE, 0);
+ }
+ WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, ih_doorbell_rtpr);
+
++ ih = &adev->irq.ih1;
++ if (ih->ring_size) {
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
++ (ih->gpu_addr >> 40) & 0xff);
++
++ ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
++ ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
++
++ /* set rptr, wptr to 0 */
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
++ }
++
++ ih = &adev->irq.ih2;
++ if (ih->ring_size) {
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
++ (ih->gpu_addr >> 40) & 0xff);
++
++ ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
++ ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
++
++ /* set rptr, wptr to 0 */
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
++ WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
++ }
++
+ tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
+ tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
+ CLIENT18_IS_STORM_CLIENT, 1);
+@@ -297,6 +381,17 @@ static int vega10_ih_sw_init(void *handle)
+ if (r)
+ return r;
+
++ if (adev->asic_type == CHIP_VEGA10) {
++ r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
++ if (r)
++ return r;
++
++ r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
++ if (r)
++ return r;
++ }
++
++ /* TODO add doorbell for IH1 & IH2 as well */
+ adev->irq.ih.use_doorbell = true;
+ adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
+
+@@ -310,6 +405,8 @@ static int vega10_ih_sw_fini(void *handle)
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ amdgpu_irq_fini(adev);
++ amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
++ amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
+ amdgpu_ih_ring_fini(adev, &adev->irq.ih);
+
+ return 0;
+--
+2.17.1
+