mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts
Why: Setting IH_RB_WPTR register to 0 will not clear the RB_OVERFLOW bit if RB_ENABLE is not set. How to fix: Set WPTR_OVERFLOW_CLEAR bit after RB_ENABLE bit is set. The RB_ENABLE bit is required to be set, together with WPTR_OVERFLOW_ENABLE bit so that setting WPTR_OVERFLOW_CLEAR bit would clear the RB_OVERFLOW. Signed-off-by: Danijel Slivka <danijel.slivka@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									bf826ba9b4
								
							
						
					
					
						commit
						afbf7955ff
					
				
					 1 changed files with 28 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -135,6 +135,34 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev,
 | 
			
		|||
 | 
			
		||||
	tmp = RREG32(ih_regs->ih_rb_cntl);
 | 
			
		||||
	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
 | 
			
		||||
 | 
			
		||||
	if (enable) {
 | 
			
		||||
		/* Unset the CLEAR_OVERFLOW bit to make sure the next step
 | 
			
		||||
		 * is switching the bit from 0 to 1
 | 
			
		||||
		 */
 | 
			
		||||
		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
 | 
			
		||||
		if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
 | 
			
		||||
			if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
 | 
			
		||||
				return -ETIMEDOUT;
 | 
			
		||||
		} else {
 | 
			
		||||
			WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Clear RB_OVERFLOW bit */
 | 
			
		||||
		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
 | 
			
		||||
		if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
 | 
			
		||||
			if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
 | 
			
		||||
				return -ETIMEDOUT;
 | 
			
		||||
		} else {
 | 
			
		||||
			WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
 | 
			
		||||
		 * can be detected.
 | 
			
		||||
		 */
 | 
			
		||||
		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* enable_intr field is only valid in ring0 */
 | 
			
		||||
	if (ih == &adev->irq.ih)
 | 
			
		||||
		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue