diff options
author | Chunming Zhou <David1.Zhou@amd.com> | 2016-07-18 04:59:24 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-08-08 11:32:09 -0400 |
commit | 50b0197abfa062d05f5f14a94e04ed7fd45cb003 (patch) | |
tree | 423dcc7dd1e240f75b7bc5fa5e795aa42868c22b | |
parent | e702a68051b174e87df62bbc0204809b5c1ba3e5 (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>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 59 |
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 | ||
1095 | static int gmc_v8_0_soft_reset(void *handle) | 1095 | static 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 | |||
1121 | static 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 | ||
1136 | static 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 | ||
1167 | static 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 | |||
1142 | static int gmc_v8_0_vm_fault_interrupt_state(struct amdgpu_device *adev, | 1178 | static 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 | }; |