aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorChunming Zhou <David1.Zhou@amd.com>2016-07-18 04:59:24 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-08-08 11:32:09 -0400
commit50b0197abfa062d05f5f14a94e04ed7fd45cb003 (patch)
tree423dcc7dd1e240f75b7bc5fa5e795aa42868c22b /drivers/gpu/drm/amd
parente702a68051b174e87df62bbc0204809b5c1ba3e5 (diff)
drm/amdgpu: implement gmc8 check/pre/post_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')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c59
2 files changed, 51 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 17600b477cf9..e4a731bc9fc1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -677,6 +677,8 @@ struct amdgpu_mc {
677 uint32_t fw_version; 677 uint32_t fw_version;
678 struct amdgpu_irq_src vm_fault; 678 struct amdgpu_irq_src vm_fault;
679 uint32_t vram_type; 679 uint32_t vram_type;
680 uint32_t srbm_soft_reset;
681 struct amdgpu_mode_mc_save save;
680}; 682};
681 683
682/* 684/*
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index 717359d3ba8c..0a23b8394705 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -1092,9 +1092,8 @@ static int gmc_v8_0_wait_for_idle(void *handle)
1092 1092
1093} 1093}
1094 1094
1095static int gmc_v8_0_soft_reset(void *handle) 1095static int gmc_v8_0_check_soft_reset(void *handle)
1096{ 1096{
1097 struct amdgpu_mode_mc_save save;
1098 u32 srbm_soft_reset = 0; 1097 u32 srbm_soft_reset = 0;
1099 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1098 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1100 u32 tmp = RREG32(mmSRBM_STATUS); 1099 u32 tmp = RREG32(mmSRBM_STATUS);
@@ -1109,13 +1108,42 @@ static int gmc_v8_0_soft_reset(void *handle)
1109 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, 1108 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
1110 SRBM_SOFT_RESET, SOFT_RESET_MC, 1); 1109 SRBM_SOFT_RESET, SOFT_RESET_MC, 1);
1111 } 1110 }
1112
1113 if (srbm_soft_reset) { 1111 if (srbm_soft_reset) {
1114 gmc_v8_0_mc_stop(adev, &save); 1112 adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = true;
1115 if (gmc_v8_0_wait_for_idle((void *)adev)) { 1113 adev->mc.srbm_soft_reset = srbm_soft_reset;
1116 dev_warn(adev->dev, "Wait for GMC idle timed out !\n"); 1114 } else {
1117 } 1115 adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = false;
1116 adev->mc.srbm_soft_reset = 0;
1117 }
1118 return 0;
1119}
1120
1121static int gmc_v8_0_pre_soft_reset(void *handle)
1122{
1123 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1124
1125 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
1126 return 0;
1127
1128 gmc_v8_0_mc_stop(adev, &adev->mc.save);
1129 if (gmc_v8_0_wait_for_idle(adev)) {
1130 dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
1131 }
1132
1133 return 0;
1134}
1118 1135
1136static int gmc_v8_0_soft_reset(void *handle)
1137{
1138 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1139 u32 srbm_soft_reset;
1140
1141 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
1142 return 0;
1143 srbm_soft_reset = adev->mc.srbm_soft_reset;
1144
1145 if (srbm_soft_reset) {
1146 u32 tmp;
1119 1147
1120 tmp = RREG32(mmSRBM_SOFT_RESET); 1148 tmp = RREG32(mmSRBM_SOFT_RESET);
1121 tmp |= srbm_soft_reset; 1149 tmp |= srbm_soft_reset;
@@ -1131,14 +1159,22 @@ static int gmc_v8_0_soft_reset(void *handle)
1131 1159
1132 /* Wait a little for things to settle down */ 1160 /* Wait a little for things to settle down */
1133 udelay(50); 1161 udelay(50);
1134
1135 gmc_v8_0_mc_resume(adev, &save);
1136 udelay(50);
1137 } 1162 }
1138 1163
1139 return 0; 1164 return 0;
1140} 1165}
1141 1166
1167static int gmc_v8_0_post_soft_reset(void *handle)
1168{
1169 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1170
1171 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
1172 return 0;
1173
1174 gmc_v8_0_mc_resume(adev, &adev->mc.save);
1175 return 0;
1176}
1177
1142static int gmc_v8_0_vm_fault_interrupt_state(struct amdgpu_device *adev, 1178static int gmc_v8_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
1143 struct amdgpu_irq_src *src, 1179 struct amdgpu_irq_src *src,
1144 unsigned type, 1180 unsigned type,
@@ -1406,7 +1442,10 @@ const struct amd_ip_funcs gmc_v8_0_ip_funcs = {
1406 .resume = gmc_v8_0_resume, 1442 .resume = gmc_v8_0_resume,
1407 .is_idle = gmc_v8_0_is_idle, 1443 .is_idle = gmc_v8_0_is_idle,
1408 .wait_for_idle = gmc_v8_0_wait_for_idle, 1444 .wait_for_idle = gmc_v8_0_wait_for_idle,
1445 .check_soft_reset = gmc_v8_0_check_soft_reset,
1446 .pre_soft_reset = gmc_v8_0_pre_soft_reset,
1409 .soft_reset = gmc_v8_0_soft_reset, 1447 .soft_reset = gmc_v8_0_soft_reset,
1448 .post_soft_reset = gmc_v8_0_post_soft_reset,
1410 .set_clockgating_state = gmc_v8_0_set_clockgating_state, 1449 .set_clockgating_state = gmc_v8_0_set_clockgating_state,
1411 .set_powergating_state = gmc_v8_0_set_powergating_state, 1450 .set_powergating_state = gmc_v8_0_set_powergating_state,
1412}; 1451};