[PATCH 9/9] drm/amdgpu: enable IH ring 1 and ring 2

Huang, Ray Ray.Huang at amd.com
Wed Sep 26 08:49:01 UTC 2018


> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Christian K?nig
> Sent: Monday, September 24, 2018 8:38 PM
> To: amd-gfx at lists.freedesktop.org
> 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 at amd.com>

Reviewed-by: Huang Rui <ray.huang at amd.com>

> ---
>  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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list