diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/tonga_ih.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 60 | 
1 files changed, 25 insertions, 35 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index 15da06ddeb75..a20b711a6756 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -99,9 +99,9 @@ static void tonga_ih_disable_interrupts(struct amdgpu_device *adev)   */  static int tonga_ih_irq_init(struct amdgpu_device *adev)  { -	int rb_bufsz;  	u32 interrupt_cntl, ih_rb_cntl, ih_doorbell_rtpr; -	u64 wptr_off; +	struct amdgpu_ih_ring *ih = &adev->irq.ih; +	int rb_bufsz;  	/* disable irqs */  	tonga_ih_disable_interrupts(adev); @@ -118,10 +118,7 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev)  	WREG32(mmINTERRUPT_CNTL, interrupt_cntl);  	/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/ -	if (adev->irq.ih.use_bus_addr) -		WREG32(mmIH_RB_BASE, adev->irq.ih.rb_dma_addr >> 8); -	else -		WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8); +	WREG32(mmIH_RB_BASE, ih->gpu_addr >> 8);  	rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);  	ih_rb_cntl = REG_SET_FIELD(0, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); @@ -136,12 +133,8 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev)  	WREG32(mmIH_RB_CNTL, ih_rb_cntl);  	/* set the writeback address whether it's enabled or not */ -	if (adev->irq.ih.use_bus_addr) -		wptr_off = adev->irq.ih.rb_dma_addr + (adev->irq.ih.wptr_offs * 4); -	else -		wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4); -	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off)); -	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF); +	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr)); +	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);  	/* set rptr, wptr to 0 */  	WREG32(mmIH_RB_RPTR, 0); @@ -193,14 +186,12 @@ 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]); -	else -		wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); +	wptr = le32_to_cpu(*ih->wptr_cpu);  	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {  		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); @@ -209,13 +200,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);  }  /** @@ -227,16 +218,17 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)   * position and also advance the position.   */  static void tonga_ih_decode_iv(struct amdgpu_device *adev, -				 struct amdgpu_iv_entry *entry) +			       struct amdgpu_ih_ring *ih, +			       struct amdgpu_iv_entry *entry)  {  	/* wptr/rptr are in bytes! */ -	u32 ring_index = adev->irq.ih.rptr >> 2; +	u32 ring_index = ih->rptr >> 2;  	uint32_t dw[4]; -	dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); -	dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]); -	dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]); -	dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); +	dw[0] = le32_to_cpu(ih->ring[ring_index + 0]); +	dw[1] = le32_to_cpu(ih->ring[ring_index + 1]); +	dw[2] = le32_to_cpu(ih->ring[ring_index + 2]); +	dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);  	entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;  	entry->src_id = dw[0] & 0xff; @@ -246,7 +238,7 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,  	entry->pasid = (dw[2] >> 16) & 0xffff;  	/* wptr/rptr are in bytes! */ -	adev->irq.ih.rptr += 16; +	ih->rptr += 16;  }  /** @@ -256,17 +248,15 @@ 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; -		else -			adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; -		WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr); +		*ih->rptr_cpu = ih->rptr; +		WDOORBELL32(ih->doorbell_index, ih->rptr);  	} else { -		WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); +		WREG32(mmIH_RB_RPTR, ih->rptr);  	}  } | 
