[PATCH 07/11] drm/amdgpu: enable IH ring 1 and ring 2 v2

Christian König ckoenig.leichtzumerken at gmail.com
Fri Nov 30 16:04:56 UTC 2018


Am 30.11.18 um 17:01 schrieb Alex Deucher:
> On Fri, Nov 30, 2018 at 7:36 AM Christian König
> <ckoenig.leichtzumerken at gmail.com> wrote:
>> 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
>>
>> Signed-off-by: Christian König <christian.koenig at amd.com>
> We may want to guard this with some flag so we can easily disable it
> (like we did for the paging queue) in case we run into issues on any
> asics.

This should actually fix some issues since when you currently enable 
sources which go to ring 1 & 2 the hardware just crashes.

But I can add some checking if the rings are actually allocated. This 
way we can disable them by just commenting out two lines.

Christian.

>
> Alex
>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |   4 +-
>>   drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 129 +++++++++++++++++++-----
>>   2 files changed, 107 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
>> index f6ce171cb8aa..7e06fa64321a 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 3e9ebb0de94d..562fd036bb9e 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);
>> @@ -290,6 +360,15 @@ static int vega10_ih_sw_init(void *handle)
>>          if (r)
>>                  return r;
>>
>> +       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;
>>
>> @@ -303,6 +382,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
>>
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx



More information about the amd-gfx mailing list