[PATCH 02/14] drm/amdgpu: implement gfx8 check_soft_reset
Christian König
deathsimple at vodafone.de
Tue Jul 19 09:12:58 UTC 2016
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,
More information about the amd-gfx
mailing list