[PATCH 02/14] drm/amdgpu: implement gfx8 check_soft_reset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am 19.07.2016 um 10:13 schrieb Chunming Zhou:
> Change-Id: I68ccbb1d56ea8cf28630f8a0c49fb509220efbb3
> Signed-off-by: Chunming Zhou <David1.Zhou at amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   2 +
>   drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 133 ++++++++++++++++++++--------------
>   2 files changed, 80 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 15673dd..26f9761 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1979,6 +1979,8 @@ struct amdgpu_ip_block_status {
>   	bool sw;
>   	bool hw;
>   	bool hang;
> +	u32 grbm_soft_reset;
> +	u32 srbm_soft_reset;

I would rather put those into the  amdgpu_gfx structure.

Christian.

>   };
>   
>   struct amdgpu_device {
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> index c98129b..9027c3b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> @@ -5047,11 +5047,11 @@ static int gfx_v8_0_wait_for_idle(void *handle)
>   	return -ETIMEDOUT;
>   }
>   
> -static int gfx_v8_0_soft_reset(void *handle)
> +static int gfx_v8_0_check_soft_reset(void *handle)
>   {
> +	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>   	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
>   	u32 tmp;
> -	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>   
>   	/* GRBM_STATUS */
>   	tmp = RREG32(mmGRBM_STATUS);
> @@ -5060,16 +5060,12 @@ static int gfx_v8_0_soft_reset(void *handle)
>   		   GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK |
>   		   GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK |
>   		   GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK |
> -		   GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK)) {
> +		   GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK |
> +		   GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) {
>   		grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
>   						GRBM_SOFT_RESET, SOFT_RESET_CP, 1);
>   		grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
>   						GRBM_SOFT_RESET, SOFT_RESET_GFX, 1);
> -	}
> -
> -	if (tmp & (GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) {
> -		grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
> -						GRBM_SOFT_RESET, SOFT_RESET_CP, 1);
>   		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
>   						SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1);
>   	}
> @@ -5080,73 +5076,99 @@ static int gfx_v8_0_soft_reset(void *handle)
>   		grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
>   						GRBM_SOFT_RESET, SOFT_RESET_RLC, 1);
>   
> +	if (REG_GET_FIELD(tmp, GRBM_STATUS2, CPF_BUSY) ||
> +	    REG_GET_FIELD(tmp, GRBM_STATUS2, CPC_BUSY) ||
> +	    REG_GET_FIELD(tmp, GRBM_STATUS2, CPG_BUSY)) {
> +		grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET,
> +						SOFT_RESET_CPF, 1);
> +		grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET,
> +						SOFT_RESET_CPC, 1);
> +		grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET,
> +						SOFT_RESET_CPG, 1);
> +		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET,
> +						SOFT_RESET_GRBM, 1);
> +	}
> +
>   	/* SRBM_STATUS */
>   	tmp = RREG32(mmSRBM_STATUS);
>   	if (REG_GET_FIELD(tmp, SRBM_STATUS, GRBM_RQ_PENDING))
>   		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
>   						SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1);
> +	if (REG_GET_FIELD(tmp, SRBM_STATUS, SEM_BUSY))
> +		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
> +						SRBM_SOFT_RESET, SOFT_RESET_SEM, 1);
>   
>   	if (grbm_soft_reset || srbm_soft_reset) {
> -		/* stop the rlc */
> -		gfx_v8_0_rlc_stop(adev);
> +		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = true;
> +		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].grbm_soft_reset = grbm_soft_reset;
> +		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].srbm_soft_reset = srbm_soft_reset;
> +	} else {
> +		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = false;
> +		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].grbm_soft_reset = 0;
> +		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].srbm_soft_reset = 0;
> +	}
>   
> -		/* Disable GFX parsing/prefetching */
> -		gfx_v8_0_cp_gfx_enable(adev, false);
> +	return 0;
> +}
>   
> -		/* Disable MEC parsing/prefetching */
> -		gfx_v8_0_cp_compute_enable(adev, false);
> +static int gfx_v8_0_soft_reset(void *handle)
> +{
> +	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
> +	u32 tmp;
>   
> -		if (grbm_soft_reset || srbm_soft_reset) {
> -			tmp = RREG32(mmGMCON_DEBUG);
> -			tmp = REG_SET_FIELD(tmp,
> -					    GMCON_DEBUG, GFX_STALL, 1);
> -			tmp = REG_SET_FIELD(tmp,
> -					    GMCON_DEBUG, GFX_CLEAR, 1);
> -			WREG32(mmGMCON_DEBUG, tmp);
> +	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
> +		return 0;
>   
> -			udelay(50);
> -		}
> +	grbm_soft_reset = adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].grbm_soft_reset;
> +	srbm_soft_reset = adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].srbm_soft_reset;
>   
> -		if (grbm_soft_reset) {
> -			tmp = RREG32(mmGRBM_SOFT_RESET);
> -			tmp |= grbm_soft_reset;
> -			dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
> -			WREG32(mmGRBM_SOFT_RESET, tmp);
> -			tmp = RREG32(mmGRBM_SOFT_RESET);
> +	if (grbm_soft_reset || srbm_soft_reset) {
> +		tmp = RREG32(mmGMCON_DEBUG);
> +		tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 1);
> +		tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 1);
> +		WREG32(mmGMCON_DEBUG, tmp);
> +		udelay(50);
> +	}
>   
> -			udelay(50);
> +	if (grbm_soft_reset) {
> +		tmp = RREG32(mmGRBM_SOFT_RESET);
> +		tmp |= grbm_soft_reset;
> +		dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
> +		WREG32(mmGRBM_SOFT_RESET, tmp);
> +		tmp = RREG32(mmGRBM_SOFT_RESET);
>   
> -			tmp &= ~grbm_soft_reset;
> -			WREG32(mmGRBM_SOFT_RESET, tmp);
> -			tmp = RREG32(mmGRBM_SOFT_RESET);
> -		}
> +		udelay(50);
>   
> -		if (srbm_soft_reset) {
> -			tmp = RREG32(mmSRBM_SOFT_RESET);
> -			tmp |= srbm_soft_reset;
> -			dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
> -			WREG32(mmSRBM_SOFT_RESET, tmp);
> -			tmp = RREG32(mmSRBM_SOFT_RESET);
> +		tmp &= ~grbm_soft_reset;
> +		WREG32(mmGRBM_SOFT_RESET, tmp);
> +		tmp = RREG32(mmGRBM_SOFT_RESET);
> +	}
>   
> -			udelay(50);
> +	if (srbm_soft_reset) {
> +		tmp = RREG32(mmSRBM_SOFT_RESET);
> +		tmp |= srbm_soft_reset;
> +		dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
> +		WREG32(mmSRBM_SOFT_RESET, tmp);
> +		tmp = RREG32(mmSRBM_SOFT_RESET);
>   
> -			tmp &= ~srbm_soft_reset;
> -			WREG32(mmSRBM_SOFT_RESET, tmp);
> -			tmp = RREG32(mmSRBM_SOFT_RESET);
> -		}
> +		udelay(50);
>   
> -		if (grbm_soft_reset || srbm_soft_reset) {
> -			tmp = RREG32(mmGMCON_DEBUG);
> -			tmp = REG_SET_FIELD(tmp,
> -					    GMCON_DEBUG, GFX_STALL, 0);
> -			tmp = REG_SET_FIELD(tmp,
> -					    GMCON_DEBUG, GFX_CLEAR, 0);
> -			WREG32(mmGMCON_DEBUG, tmp);
> -		}
> +		tmp &= ~srbm_soft_reset;
> +		WREG32(mmSRBM_SOFT_RESET, tmp);
> +		tmp = RREG32(mmSRBM_SOFT_RESET);
> +	}
>   
> -		/* Wait a little for things to settle down */
> -		udelay(50);
> +	if (grbm_soft_reset || srbm_soft_reset) {
> +		tmp = RREG32(mmGMCON_DEBUG);
> +		tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 0);
> +		tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 0);
> +		WREG32(mmGMCON_DEBUG, tmp);
>   	}
> +
> +	/* Wait a little for things to settle down */
> +	udelay(50);
> +
>   	return 0;
>   }
>   
> @@ -6387,6 +6409,7 @@ const struct amd_ip_funcs gfx_v8_0_ip_funcs = {
>   	.resume = gfx_v8_0_resume,
>   	.is_idle = gfx_v8_0_is_idle,
>   	.wait_for_idle = gfx_v8_0_wait_for_idle,
> +	.check_soft_reset = gfx_v8_0_check_soft_reset,
>   	.soft_reset = gfx_v8_0_soft_reset,
>   	.set_clockgating_state = gfx_v8_0_set_clockgating_state,
>   	.set_powergating_state = gfx_v8_0_set_powergating_state,



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux