On Mon, Sep 24, 2018 at 02:38:18PM +0200, Christian König wrote: > Let's start to support multiple rings. > > Signed-off-by: Christian König <christian.koenig@xxxxxxx> Reviewed-by: Huang Rui <ray.huang@xxxxxxx> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 6 +++--- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 ++++---- > drivers/gpu/drm/amd/amdgpu/cik_ih.c | 16 +++++++++------- > drivers/gpu/drm/amd/amdgpu/cz_ih.c | 16 +++++++++------- > drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 16 +++++++++------- > drivers/gpu/drm/amd/amdgpu/si_ih.c | 16 +++++++++------- > drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 28 +++++++++++++++------------- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 32 +++++++++++++++++--------------- > 8 files changed, 75 insertions(+), 63 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > index 8af67f649660..fb8dd6179926 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > @@ -137,7 +137,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, > if (!ih->enabled || adev->shutdown) > return IRQ_NONE; > > - wptr = amdgpu_ih_get_wptr(adev); > + wptr = amdgpu_ih_get_wptr(adev, ih); > > restart_ih: > /* is somebody else already processing irqs? */ > @@ -154,11 +154,11 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, > ih->rptr &= ih->ptr_mask; > } > > - amdgpu_ih_set_rptr(adev); > + amdgpu_ih_set_rptr(adev, ih); > atomic_set(&ih->lock, 0); > > /* make sure wptr hasn't changed while processing */ > - wptr = amdgpu_ih_get_wptr(adev); > + wptr = amdgpu_ih_get_wptr(adev, ih); > if (wptr != ih->rptr) > goto restart_ih; > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > index d88f82321ee4..61967e7b64a7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > @@ -52,12 +52,12 @@ struct amdgpu_ih_ring { > /* provided by the ih block */ > struct amdgpu_ih_funcs { > /* ring read/write ptr handling, called from interrupt context */ > - u32 (*get_wptr)(struct amdgpu_device *adev); > - void (*set_rptr)(struct amdgpu_device *adev); > + u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > + void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > }; > > -#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih.funcs->get_wptr((adev)) > -#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih.funcs->set_rptr((adev)) > +#define amdgpu_ih_get_wptr(adev, ih) (ih)->funcs->get_wptr((adev), (ih)) > +#define amdgpu_ih_set_rptr(adev, ih) (ih)->funcs->set_rptr((adev), (ih)) > > int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, > unsigned ring_size, bool use_bus_addr); > diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c > index 161f0225749c..341092768809 100644 > --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c > @@ -183,11 +183,12 @@ static void cik_ih_irq_disable(struct amdgpu_device *adev) > * Used by cik_irq_process(). > * Returns the value of the wptr. > */ > -static u32 cik_ih_get_wptr(struct amdgpu_device *adev) > +static u32 cik_ih_get_wptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > u32 wptr, tmp; > > - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); > > if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) { > wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK; > @@ -196,13 +197,13 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) > * this should allow us to catchup. > */ > dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", > - wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); > - adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; > + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); > + ih->rptr = (wptr + 16) & ih->ptr_mask; > tmp = RREG32(mmIH_RB_CNTL); > tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; > WREG32(mmIH_RB_CNTL, tmp); > } > - return (wptr & adev->irq.ih.ptr_mask); > + return (wptr & ih->ptr_mask); > } > > /* CIK IV Ring > @@ -294,9 +295,10 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev, > * > * Set the IH ring buffer rptr. > */ > -static void cik_ih_set_rptr(struct amdgpu_device *adev) > +static void cik_ih_set_rptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > - WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); > + WREG32(mmIH_RB_RPTR, ih->rptr); > } > > static int cik_ih_early_init(void *handle) > diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c > index 648ecd774611..6ed750187ad7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c > @@ -185,11 +185,12 @@ static void cz_ih_irq_disable(struct amdgpu_device *adev) > * Used by cz_irq_process(VI). > * Returns the value of the wptr. > */ > -static u32 cz_ih_get_wptr(struct amdgpu_device *adev) > +static u32 cz_ih_get_wptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > u32 wptr, tmp; > > - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); > > if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { > wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); > @@ -198,13 +199,13 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev) > * this should allow us to catchup. > */ > dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", > - wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); > - adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; > + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); > + ih->rptr = (wptr + 16) & ih->ptr_mask; > tmp = RREG32(mmIH_RB_CNTL); > tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); > WREG32(mmIH_RB_CNTL, tmp); > } > - return (wptr & adev->irq.ih.ptr_mask); > + return (wptr & ih->ptr_mask); > } > > /** > @@ -273,9 +274,10 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev, > * > * Set the IH ring buffer rptr. > */ > -static void cz_ih_set_rptr(struct amdgpu_device *adev) > +static void cz_ih_set_rptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > - WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); > + WREG32(mmIH_RB_RPTR, ih->rptr); > } > > static int cz_ih_early_init(void *handle) > diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c > index 6139186ccd36..c779d708c306 100644 > --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c > @@ -185,11 +185,12 @@ static void iceland_ih_irq_disable(struct amdgpu_device *adev) > * Used by cz_irq_process(VI). > * Returns the value of the wptr. > */ > -static u32 iceland_ih_get_wptr(struct amdgpu_device *adev) > +static u32 iceland_ih_get_wptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > u32 wptr, tmp; > > - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); > > if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { > wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); > @@ -198,13 +199,13 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev) > * this should allow us to catchup. > */ > dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", > - wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); > - adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; > + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); > + ih->rptr = (wptr + 16) & ih->ptr_mask; > tmp = RREG32(mmIH_RB_CNTL); > tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); > WREG32(mmIH_RB_CNTL, tmp); > } > - return (wptr & adev->irq.ih.ptr_mask); > + return (wptr & ih->ptr_mask); > } > > /** > @@ -273,9 +274,10 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev, > * > * Set the IH ring buffer rptr. > */ > -static void iceland_ih_set_rptr(struct amdgpu_device *adev) > +static void iceland_ih_set_rptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > - WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); > + WREG32(mmIH_RB_RPTR, ih->rptr); > } > > static int iceland_ih_early_init(void *handle) > diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c > index 16f212f3b534..a005824d8b9a 100644 > --- a/drivers/gpu/drm/amd/amdgpu/si_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c > @@ -100,22 +100,23 @@ static void si_ih_irq_disable(struct amdgpu_device *adev) > mdelay(1); > } > > -static u32 si_ih_get_wptr(struct amdgpu_device *adev) > +static u32 si_ih_get_wptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > u32 wptr, tmp; > > - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); > > if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) { > wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK; > dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", > - wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); > - adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; > + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); > + ih->rptr = (wptr + 16) & ih->ptr_mask; > tmp = RREG32(IH_RB_CNTL); > tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; > WREG32(IH_RB_CNTL, tmp); > } > - return (wptr & adev->irq.ih.ptr_mask); > + return (wptr & ih->ptr_mask); > } > > /** > @@ -151,9 +152,10 @@ static void si_ih_decode_iv(struct amdgpu_device *adev, > adev->irq.ih.rptr += 16; > } > > -static void si_ih_set_rptr(struct amdgpu_device *adev) > +static void si_ih_set_rptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > - WREG32(IH_RB_RPTR, adev->irq.ih.rptr); > + WREG32(IH_RB_RPTR, ih->rptr); > } > > static int si_ih_early_init(void *handle) > diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c > index 6120ac3c7667..3618dc0c6804 100644 > --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c > @@ -193,14 +193,15 @@ static void tonga_ih_irq_disable(struct amdgpu_device *adev) > * Used by cz_irq_process(VI). > * Returns the value of the wptr. > */ > -static u32 tonga_ih_get_wptr(struct amdgpu_device *adev) > +static u32 tonga_ih_get_wptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > u32 wptr, tmp; > > if (adev->irq.ih.use_bus_addr) > - wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(ih->ring[ih->wptr_offs]); > else > - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); > > if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { > wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); > @@ -209,13 +210,13 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev) > * this should allow us to catchup. > */ > dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", > - wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); > - adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; > + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); > + ih->rptr = (wptr + 16) & ih->ptr_mask; > tmp = RREG32(mmIH_RB_CNTL); > tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); > WREG32(mmIH_RB_CNTL, tmp); > } > - return (wptr & adev->irq.ih.ptr_mask); > + return (wptr & ih->ptr_mask); > } > > /** > @@ -284,17 +285,18 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev, > * > * Set the IH ring buffer rptr. > */ > -static void tonga_ih_set_rptr(struct amdgpu_device *adev) > +static void tonga_ih_set_rptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > - if (adev->irq.ih.use_doorbell) { > + if (ih->use_doorbell) { > /* XXX check if swapping is necessary on BE */ > - if (adev->irq.ih.use_bus_addr) > - adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; > + if (ih->use_bus_addr) > + ih->ring[ih->rptr_offs] = ih->rptr; > else > - adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; > - WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr); > + adev->wb.wb[ih->rptr_offs] = ih->rptr; > + WDOORBELL32(ih->doorbell_index, ih->rptr); > } else { > - WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); > + WREG32(mmIH_RB_RPTR, ih->rptr); > } > } > > diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > index a9737adf8392..12d4e3ec851e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > @@ -191,14 +191,15 @@ static void vega10_ih_irq_disable(struct amdgpu_device *adev) > * ring buffer overflow and deal with it. > * Returns the value of the wptr. > */ > -static u32 vega10_ih_get_wptr(struct amdgpu_device *adev) > +static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > u32 wptr, tmp; > > - if (adev->irq.ih.use_bus_addr) > - wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]); > + if (ih->use_bus_addr) > + wptr = le32_to_cpu(ih->ring[ih->wptr_offs]); > else > - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); > > if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { > wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); > @@ -207,16 +208,16 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev) > * from the last not overwritten vector (wptr + 32). Hopefully > * this should allow us to catchup. > */ > - tmp = (wptr + 32) & adev->irq.ih.ptr_mask; > + tmp = (wptr + 32) & ih->ptr_mask; > dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", > - wptr, adev->irq.ih.rptr, tmp); > - adev->irq.ih.rptr = tmp; > + wptr, ih->rptr, tmp); > + ih->rptr = tmp; > > tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL)); > tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); > WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp); > } > - return (wptr & adev->irq.ih.ptr_mask); > + return (wptr & ih->ptr_mask); > } > > /** > @@ -353,17 +354,18 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev, > * > * Set the IH ring buffer rptr. > */ > -static void vega10_ih_set_rptr(struct amdgpu_device *adev) > +static void vega10_ih_set_rptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > - if (adev->irq.ih.use_doorbell) { > + if (ih->use_doorbell) { > /* XXX check if swapping is necessary on BE */ > - if (adev->irq.ih.use_bus_addr) > - adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; > + if (ih->use_bus_addr) > + ih->ring[ih->rptr_offs] = ih->rptr; > else > - adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; > - WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr); > + adev->wb.wb[ih->rptr_offs] = ih->rptr; > + WDOORBELL32(ih->doorbell_index, ih->rptr); > } else { > - WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, adev->irq.ih.rptr); > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); > } > } > > -- > 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