[PATCH 10/11] drm/amdgpu: add support for self irq on Vega10

Alex Deucher alexdeucher at gmail.com
Fri Nov 30 16:11:18 UTC 2018


On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken at gmail.com> wrote:
>
> This finally enables processing of ring 1 & 2.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 68 ++++++++++++++++++++++++--
>  1 file changed, 63 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index 562fd036bb9e..f5c5ea628fdf 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -258,7 +258,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);
>
> @@ -274,9 +274,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);
> +               else if (ih == &adev->irq.ih2)
> +                       reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
> +               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);
>         }
>         return (wptr & ih->ptr_mask);
>  }
> @@ -338,9 +347,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)
> @@ -348,13 +400,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
>
> _______________________________________________
> 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