> -----Original Message----- > From: amd-gfx [mailto:amd-gfx-bounces@xxxxxxxxxxxxxxxxxxxxx] On Behalf > Of Christian K?nig > Sent: Monday, September 24, 2018 8:38 PM > To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx > Subject: [PATCH 9/9] drm/amdgpu: enable IH ring 1 and ring 2 > > 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. > > Signed-off-by: Christian König <christian.koenig@xxxxxxx> Reviewed-by: Huang Rui <ray.huang@xxxxxxx> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 4 +- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 129 > +++++++++++++++++++++++++------- > 2 files changed, 106 insertions(+), 27 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > index 3cc0e7ce40a0..0c6af0b38490 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > @@ -93,8 +93,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; > > /* gen irq stuff */ > struct irq_domain *domain; /* GPU irq controller > domain */ > diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > index b4330eccee04..2d2036e0c8b1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > @@ -50,6 +50,16 @@ 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; > + > + 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; > + > + 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 +81,47 @@ 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; > + > + 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; > + > + 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 +137,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 +147,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,18 +170,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); > adev->nbio_funcs->ih_doorbell_range(adev, adev- > >irq.ih.use_doorbell, > adev->irq.ih.doorbell_index); > > + ih = &adev->irq.ih1; > + /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the > ring buffer*/ > + 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; > + /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the > ring buffer*/ > + 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); > @@ -333,7 +403,6 @@ static void vega10_ih_decode_iv(struct > amdgpu_device *adev, > entry->src_data[2] = dw[6]; > entry->src_data[3] = dw[7]; > > - > /* wptr/rptr are in bytes! */ > adev->irq.ih.rptr += 32; > } > @@ -374,6 +443,14 @@ static int vega10_ih_sw_init(void *handle) > if (r) > return r; > > + r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, 256 * 1024, true); > + if (r) > + return r; > + > + r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, 256 * 1024, true); > + if (r) > + return r; > + > adev->irq.ih.use_doorbell = true; > adev->irq.ih.doorbell_index = AMDGPU_DOORBELL64_IH << 1; > > @@ -387,6 +464,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.14.1 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx