diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 49 | 
3 files changed, 48 insertions, 3 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 47f29f9e6df5..3640b124851e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1976,7 +1976,6 @@ int amdgpu_pre_soft_reset(struct amdgpu_device *adev)  static bool amdgpu_need_full_reset(struct amdgpu_device *adev)  {  	if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang || -	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang ||  	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang ||  	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang ||  	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang || diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index 7ef09352e534..f016464035b8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h @@ -70,6 +70,7 @@ struct amdgpu_irq {  	/* gen irq stuff */  	struct irq_domain		*domain; /* GPU irq controller domain */  	unsigned			virq[AMDGPU_MAX_IRQ_SRC_ID]; +	uint32_t                        srbm_soft_reset;  };  void amdgpu_irq_preinstall(struct drm_device *dev); diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index c92055805a45..d127d59f953a 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -373,10 +373,10 @@ static int tonga_ih_wait_for_idle(void *handle)  	return -ETIMEDOUT;  } -static int tonga_ih_soft_reset(void *handle) +static int tonga_ih_check_soft_reset(void *handle)  { -	u32 srbm_soft_reset = 0;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	u32 srbm_soft_reset = 0;  	u32 tmp = RREG32(mmSRBM_STATUS);  	if (tmp & SRBM_STATUS__IH_BUSY_MASK) @@ -384,6 +384,48 @@ static int tonga_ih_soft_reset(void *handle)  						SOFT_RESET_IH, 1);  	if (srbm_soft_reset) { +		adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang = true; +		adev->irq.srbm_soft_reset = srbm_soft_reset; +	} else { +		adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang = false; +		adev->irq.srbm_soft_reset = 0; +	} + +	return 0; +} + +static int tonga_ih_pre_soft_reset(void *handle) +{ +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang) +		return 0; + +	return tonga_ih_hw_fini(adev); +} + +static int tonga_ih_post_soft_reset(void *handle) +{ +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang) +		return 0; + +	return tonga_ih_hw_init(adev); +} + +static int tonga_ih_soft_reset(void *handle) +{ +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	u32 srbm_soft_reset; + +	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang) +		return 0; +	srbm_soft_reset = adev->irq.srbm_soft_reset; + +	if (srbm_soft_reset) { +		u32 tmp; +  		tmp = RREG32(mmSRBM_SOFT_RESET);  		tmp |= srbm_soft_reset;  		dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); @@ -427,7 +469,10 @@ const struct amd_ip_funcs tonga_ih_ip_funcs = {  	.resume = tonga_ih_resume,  	.is_idle = tonga_ih_is_idle,  	.wait_for_idle = tonga_ih_wait_for_idle, +	.check_soft_reset = tonga_ih_check_soft_reset, +	.pre_soft_reset = tonga_ih_pre_soft_reset,  	.soft_reset = tonga_ih_soft_reset, +	.post_soft_reset = tonga_ih_post_soft_reset,  	.set_clockgating_state = tonga_ih_set_clockgating_state,  	.set_powergating_state = tonga_ih_set_powergating_state,  }; |