diff options
author | Chunming Zhou <David1.Zhou@amd.com> | 2016-07-14 23:28:30 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-08-08 11:32:01 -0400 |
commit | 3d7c63849072747eaba6b5d35671bd9cd2d002c1 (patch) | |
tree | 8bb4490cf8c9f543c062caba08427c76bdf78dbb /drivers/gpu/drm/amd/amdgpu | |
parent | 63fbf42f7307a5911237fed3285e669d9d4d0d1a (diff) |
drm/amdgpu: implement gfx8 check_soft_reset
Signed-off-by: Chunming Zhou <David1.Zhou@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 133 |
2 files changed, 82 insertions, 55 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index a21b342ab2a3..b6e8e7a825f8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1195,6 +1195,10 @@ struct amdgpu_gfx { | |||
1195 | unsigned ce_ram_size; | 1195 | unsigned ce_ram_size; |
1196 | struct amdgpu_cu_info cu_info; | 1196 | struct amdgpu_cu_info cu_info; |
1197 | const struct amdgpu_gfx_funcs *funcs; | 1197 | const struct amdgpu_gfx_funcs *funcs; |
1198 | |||
1199 | /* reset mask */ | ||
1200 | uint32_t grbm_soft_reset; | ||
1201 | uint32_t srbm_soft_reset; | ||
1198 | }; | 1202 | }; |
1199 | 1203 | ||
1200 | int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 1204 | int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index bff8668e9e6d..87232397dbd0 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) | |||
5047 | return -ETIMEDOUT; | 5047 | return -ETIMEDOUT; |
5048 | } | 5048 | } |
5049 | 5049 | ||
5050 | static int gfx_v8_0_soft_reset(void *handle) | 5050 | static int gfx_v8_0_check_soft_reset(void *handle) |
5051 | { | 5051 | { |
5052 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
5052 | u32 grbm_soft_reset = 0, srbm_soft_reset = 0; | 5053 | u32 grbm_soft_reset = 0, srbm_soft_reset = 0; |
5053 | u32 tmp; | 5054 | u32 tmp; |
5054 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
5055 | 5055 | ||
5056 | /* GRBM_STATUS */ | 5056 | /* GRBM_STATUS */ |
5057 | tmp = RREG32(mmGRBM_STATUS); | 5057 | tmp = RREG32(mmGRBM_STATUS); |
@@ -5060,16 +5060,12 @@ static int gfx_v8_0_soft_reset(void *handle) | |||
5060 | GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK | | 5060 | GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK | |
5061 | GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK | | 5061 | GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK | |
5062 | GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK | | 5062 | GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK | |
5063 | GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK)) { | 5063 | GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK | |
5064 | GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) { | ||
5064 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, | 5065 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, |
5065 | GRBM_SOFT_RESET, SOFT_RESET_CP, 1); | 5066 | GRBM_SOFT_RESET, SOFT_RESET_CP, 1); |
5066 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, | 5067 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, |
5067 | GRBM_SOFT_RESET, SOFT_RESET_GFX, 1); | 5068 | GRBM_SOFT_RESET, SOFT_RESET_GFX, 1); |
5068 | } | ||
5069 | |||
5070 | if (tmp & (GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) { | ||
5071 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, | ||
5072 | GRBM_SOFT_RESET, SOFT_RESET_CP, 1); | ||
5073 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, | 5069 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, |
5074 | SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1); | 5070 | SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1); |
5075 | } | 5071 | } |
@@ -5080,73 +5076,99 @@ static int gfx_v8_0_soft_reset(void *handle) | |||
5080 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, | 5076 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, |
5081 | GRBM_SOFT_RESET, SOFT_RESET_RLC, 1); | 5077 | GRBM_SOFT_RESET, SOFT_RESET_RLC, 1); |
5082 | 5078 | ||
5079 | if (REG_GET_FIELD(tmp, GRBM_STATUS2, CPF_BUSY) || | ||
5080 | REG_GET_FIELD(tmp, GRBM_STATUS2, CPC_BUSY) || | ||
5081 | REG_GET_FIELD(tmp, GRBM_STATUS2, CPG_BUSY)) { | ||
5082 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, | ||
5083 | SOFT_RESET_CPF, 1); | ||
5084 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, | ||
5085 | SOFT_RESET_CPC, 1); | ||
5086 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, | ||
5087 | SOFT_RESET_CPG, 1); | ||
5088 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, | ||
5089 | SOFT_RESET_GRBM, 1); | ||
5090 | } | ||
5091 | |||
5083 | /* SRBM_STATUS */ | 5092 | /* SRBM_STATUS */ |
5084 | tmp = RREG32(mmSRBM_STATUS); | 5093 | tmp = RREG32(mmSRBM_STATUS); |
5085 | if (REG_GET_FIELD(tmp, SRBM_STATUS, GRBM_RQ_PENDING)) | 5094 | if (REG_GET_FIELD(tmp, SRBM_STATUS, GRBM_RQ_PENDING)) |
5086 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, | 5095 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, |
5087 | SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1); | 5096 | SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1); |
5097 | if (REG_GET_FIELD(tmp, SRBM_STATUS, SEM_BUSY)) | ||
5098 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, | ||
5099 | SRBM_SOFT_RESET, SOFT_RESET_SEM, 1); | ||
5088 | 5100 | ||
5089 | if (grbm_soft_reset || srbm_soft_reset) { | 5101 | if (grbm_soft_reset || srbm_soft_reset) { |
5090 | /* stop the rlc */ | 5102 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = true; |
5091 | gfx_v8_0_rlc_stop(adev); | 5103 | adev->gfx.grbm_soft_reset = grbm_soft_reset; |
5104 | adev->gfx.srbm_soft_reset = srbm_soft_reset; | ||
5105 | } else { | ||
5106 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = false; | ||
5107 | adev->gfx.grbm_soft_reset = 0; | ||
5108 | adev->gfx.srbm_soft_reset = 0; | ||
5109 | } | ||
5092 | 5110 | ||
5093 | /* Disable GFX parsing/prefetching */ | 5111 | return 0; |
5094 | gfx_v8_0_cp_gfx_enable(adev, false); | 5112 | } |
5095 | 5113 | ||
5096 | /* Disable MEC parsing/prefetching */ | 5114 | static int gfx_v8_0_soft_reset(void *handle) |
5097 | gfx_v8_0_cp_compute_enable(adev, false); | 5115 | { |
5116 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
5117 | u32 grbm_soft_reset = 0, srbm_soft_reset = 0; | ||
5118 | u32 tmp; | ||
5098 | 5119 | ||
5099 | if (grbm_soft_reset || srbm_soft_reset) { | 5120 | if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang) |
5100 | tmp = RREG32(mmGMCON_DEBUG); | 5121 | return 0; |
5101 | tmp = REG_SET_FIELD(tmp, | ||
5102 | GMCON_DEBUG, GFX_STALL, 1); | ||
5103 | tmp = REG_SET_FIELD(tmp, | ||
5104 | GMCON_DEBUG, GFX_CLEAR, 1); | ||
5105 | WREG32(mmGMCON_DEBUG, tmp); | ||
5106 | 5122 | ||
5107 | udelay(50); | 5123 | grbm_soft_reset = adev->gfx.grbm_soft_reset; |
5108 | } | 5124 | srbm_soft_reset = adev->gfx.srbm_soft_reset; |
5109 | 5125 | ||
5110 | if (grbm_soft_reset) { | 5126 | if (grbm_soft_reset || srbm_soft_reset) { |
5111 | tmp = RREG32(mmGRBM_SOFT_RESET); | 5127 | tmp = RREG32(mmGMCON_DEBUG); |
5112 | tmp |= grbm_soft_reset; | 5128 | tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 1); |
5113 | dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); | 5129 | tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 1); |
5114 | WREG32(mmGRBM_SOFT_RESET, tmp); | 5130 | WREG32(mmGMCON_DEBUG, tmp); |
5115 | tmp = RREG32(mmGRBM_SOFT_RESET); | 5131 | udelay(50); |
5132 | } | ||
5116 | 5133 | ||
5117 | udelay(50); | 5134 | if (grbm_soft_reset) { |
5135 | tmp = RREG32(mmGRBM_SOFT_RESET); | ||
5136 | tmp |= grbm_soft_reset; | ||
5137 | dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); | ||
5138 | WREG32(mmGRBM_SOFT_RESET, tmp); | ||
5139 | tmp = RREG32(mmGRBM_SOFT_RESET); | ||
5118 | 5140 | ||
5119 | tmp &= ~grbm_soft_reset; | 5141 | udelay(50); |
5120 | WREG32(mmGRBM_SOFT_RESET, tmp); | ||
5121 | tmp = RREG32(mmGRBM_SOFT_RESET); | ||
5122 | } | ||
5123 | 5142 | ||
5124 | if (srbm_soft_reset) { | 5143 | tmp &= ~grbm_soft_reset; |
5125 | tmp = RREG32(mmSRBM_SOFT_RESET); | 5144 | WREG32(mmGRBM_SOFT_RESET, tmp); |
5126 | tmp |= srbm_soft_reset; | 5145 | tmp = RREG32(mmGRBM_SOFT_RESET); |
5127 | dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); | 5146 | } |
5128 | WREG32(mmSRBM_SOFT_RESET, tmp); | ||
5129 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
5130 | 5147 | ||
5131 | udelay(50); | 5148 | if (srbm_soft_reset) { |
5149 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
5150 | tmp |= srbm_soft_reset; | ||
5151 | dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); | ||
5152 | WREG32(mmSRBM_SOFT_RESET, tmp); | ||
5153 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
5132 | 5154 | ||
5133 | tmp &= ~srbm_soft_reset; | 5155 | udelay(50); |
5134 | WREG32(mmSRBM_SOFT_RESET, tmp); | ||
5135 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
5136 | } | ||
5137 | 5156 | ||
5138 | if (grbm_soft_reset || srbm_soft_reset) { | 5157 | tmp &= ~srbm_soft_reset; |
5139 | tmp = RREG32(mmGMCON_DEBUG); | 5158 | WREG32(mmSRBM_SOFT_RESET, tmp); |
5140 | tmp = REG_SET_FIELD(tmp, | 5159 | tmp = RREG32(mmSRBM_SOFT_RESET); |
5141 | GMCON_DEBUG, GFX_STALL, 0); | 5160 | } |
5142 | tmp = REG_SET_FIELD(tmp, | ||
5143 | GMCON_DEBUG, GFX_CLEAR, 0); | ||
5144 | WREG32(mmGMCON_DEBUG, tmp); | ||
5145 | } | ||
5146 | 5161 | ||
5147 | /* Wait a little for things to settle down */ | 5162 | if (grbm_soft_reset || srbm_soft_reset) { |
5148 | udelay(50); | 5163 | tmp = RREG32(mmGMCON_DEBUG); |
5164 | tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 0); | ||
5165 | tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 0); | ||
5166 | WREG32(mmGMCON_DEBUG, tmp); | ||
5149 | } | 5167 | } |
5168 | |||
5169 | /* Wait a little for things to settle down */ | ||
5170 | udelay(50); | ||
5171 | |||
5150 | return 0; | 5172 | return 0; |
5151 | } | 5173 | } |
5152 | 5174 | ||
@@ -6334,6 +6356,7 @@ const struct amd_ip_funcs gfx_v8_0_ip_funcs = { | |||
6334 | .resume = gfx_v8_0_resume, | 6356 | .resume = gfx_v8_0_resume, |
6335 | .is_idle = gfx_v8_0_is_idle, | 6357 | .is_idle = gfx_v8_0_is_idle, |
6336 | .wait_for_idle = gfx_v8_0_wait_for_idle, | 6358 | .wait_for_idle = gfx_v8_0_wait_for_idle, |
6359 | .check_soft_reset = gfx_v8_0_check_soft_reset, | ||
6337 | .soft_reset = gfx_v8_0_soft_reset, | 6360 | .soft_reset = gfx_v8_0_soft_reset, |
6338 | .set_clockgating_state = gfx_v8_0_set_clockgating_state, | 6361 | .set_clockgating_state = gfx_v8_0_set_clockgating_state, |
6339 | .set_powergating_state = gfx_v8_0_set_powergating_state, | 6362 | .set_powergating_state = gfx_v8_0_set_powergating_state, |