diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2015-10-14 09:43:58 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-02-10 14:16:53 -0500 |
commit | ceb5bc861ef57d0007db93d2c48c4790dd39fde6 (patch) | |
tree | 930c237c2520f8ac7e89a5c4c3a540ebec04a688 /drivers/gpu/drm/amd/amdgpu | |
parent | 5907a0d8af71d17811be49f2c056b3a89660e188 (diff) |
drm/amdgpu: clean up asic level reset for CI
Drop soft reset, always use pci config reset.
Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Ken Wang <Qingqing.Wang@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/cik.c | 308 |
1 files changed, 4 insertions, 304 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index fd9c9588ef46..6b1f0539ce9d 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c | |||
@@ -1059,257 +1059,6 @@ static int cik_read_register(struct amdgpu_device *adev, u32 se_num, | |||
1059 | return -EINVAL; | 1059 | return -EINVAL; |
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | static void cik_print_gpu_status_regs(struct amdgpu_device *adev) | ||
1063 | { | ||
1064 | dev_info(adev->dev, " GRBM_STATUS=0x%08X\n", | ||
1065 | RREG32(mmGRBM_STATUS)); | ||
1066 | dev_info(adev->dev, " GRBM_STATUS2=0x%08X\n", | ||
1067 | RREG32(mmGRBM_STATUS2)); | ||
1068 | dev_info(adev->dev, " GRBM_STATUS_SE0=0x%08X\n", | ||
1069 | RREG32(mmGRBM_STATUS_SE0)); | ||
1070 | dev_info(adev->dev, " GRBM_STATUS_SE1=0x%08X\n", | ||
1071 | RREG32(mmGRBM_STATUS_SE1)); | ||
1072 | dev_info(adev->dev, " GRBM_STATUS_SE2=0x%08X\n", | ||
1073 | RREG32(mmGRBM_STATUS_SE2)); | ||
1074 | dev_info(adev->dev, " GRBM_STATUS_SE3=0x%08X\n", | ||
1075 | RREG32(mmGRBM_STATUS_SE3)); | ||
1076 | dev_info(adev->dev, " SRBM_STATUS=0x%08X\n", | ||
1077 | RREG32(mmSRBM_STATUS)); | ||
1078 | dev_info(adev->dev, " SRBM_STATUS2=0x%08X\n", | ||
1079 | RREG32(mmSRBM_STATUS2)); | ||
1080 | dev_info(adev->dev, " SDMA0_STATUS_REG = 0x%08X\n", | ||
1081 | RREG32(mmSDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET)); | ||
1082 | dev_info(adev->dev, " SDMA1_STATUS_REG = 0x%08X\n", | ||
1083 | RREG32(mmSDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET)); | ||
1084 | dev_info(adev->dev, " CP_STAT = 0x%08x\n", RREG32(mmCP_STAT)); | ||
1085 | dev_info(adev->dev, " CP_STALLED_STAT1 = 0x%08x\n", | ||
1086 | RREG32(mmCP_STALLED_STAT1)); | ||
1087 | dev_info(adev->dev, " CP_STALLED_STAT2 = 0x%08x\n", | ||
1088 | RREG32(mmCP_STALLED_STAT2)); | ||
1089 | dev_info(adev->dev, " CP_STALLED_STAT3 = 0x%08x\n", | ||
1090 | RREG32(mmCP_STALLED_STAT3)); | ||
1091 | dev_info(adev->dev, " CP_CPF_BUSY_STAT = 0x%08x\n", | ||
1092 | RREG32(mmCP_CPF_BUSY_STAT)); | ||
1093 | dev_info(adev->dev, " CP_CPF_STALLED_STAT1 = 0x%08x\n", | ||
1094 | RREG32(mmCP_CPF_STALLED_STAT1)); | ||
1095 | dev_info(adev->dev, " CP_CPF_STATUS = 0x%08x\n", RREG32(mmCP_CPF_STATUS)); | ||
1096 | dev_info(adev->dev, " CP_CPC_BUSY_STAT = 0x%08x\n", RREG32(mmCP_CPC_BUSY_STAT)); | ||
1097 | dev_info(adev->dev, " CP_CPC_STALLED_STAT1 = 0x%08x\n", | ||
1098 | RREG32(mmCP_CPC_STALLED_STAT1)); | ||
1099 | dev_info(adev->dev, " CP_CPC_STATUS = 0x%08x\n", RREG32(mmCP_CPC_STATUS)); | ||
1100 | } | ||
1101 | |||
1102 | /** | ||
1103 | * cik_gpu_check_soft_reset - check which blocks are busy | ||
1104 | * | ||
1105 | * @adev: amdgpu_device pointer | ||
1106 | * | ||
1107 | * Check which blocks are busy and return the relevant reset | ||
1108 | * mask to be used by cik_gpu_soft_reset(). | ||
1109 | * Returns a mask of the blocks to be reset. | ||
1110 | */ | ||
1111 | u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev) | ||
1112 | { | ||
1113 | u32 reset_mask = 0; | ||
1114 | u32 tmp; | ||
1115 | |||
1116 | /* GRBM_STATUS */ | ||
1117 | tmp = RREG32(mmGRBM_STATUS); | ||
1118 | if (tmp & (GRBM_STATUS__PA_BUSY_MASK | GRBM_STATUS__SC_BUSY_MASK | | ||
1119 | GRBM_STATUS__BCI_BUSY_MASK | GRBM_STATUS__SX_BUSY_MASK | | ||
1120 | GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK | | ||
1121 | GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK | | ||
1122 | GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK | | ||
1123 | GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK)) | ||
1124 | reset_mask |= AMDGPU_RESET_GFX; | ||
1125 | |||
1126 | if (tmp & (GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) | ||
1127 | reset_mask |= AMDGPU_RESET_CP; | ||
1128 | |||
1129 | /* GRBM_STATUS2 */ | ||
1130 | tmp = RREG32(mmGRBM_STATUS2); | ||
1131 | if (tmp & GRBM_STATUS2__RLC_BUSY_MASK) | ||
1132 | reset_mask |= AMDGPU_RESET_RLC; | ||
1133 | |||
1134 | /* SDMA0_STATUS_REG */ | ||
1135 | tmp = RREG32(mmSDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET); | ||
1136 | if (!(tmp & SDMA0_STATUS_REG__IDLE_MASK)) | ||
1137 | reset_mask |= AMDGPU_RESET_DMA; | ||
1138 | |||
1139 | /* SDMA1_STATUS_REG */ | ||
1140 | tmp = RREG32(mmSDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET); | ||
1141 | if (!(tmp & SDMA0_STATUS_REG__IDLE_MASK)) | ||
1142 | reset_mask |= AMDGPU_RESET_DMA1; | ||
1143 | |||
1144 | /* SRBM_STATUS2 */ | ||
1145 | tmp = RREG32(mmSRBM_STATUS2); | ||
1146 | if (tmp & SRBM_STATUS2__SDMA_BUSY_MASK) | ||
1147 | reset_mask |= AMDGPU_RESET_DMA; | ||
1148 | |||
1149 | if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) | ||
1150 | reset_mask |= AMDGPU_RESET_DMA1; | ||
1151 | |||
1152 | /* SRBM_STATUS */ | ||
1153 | tmp = RREG32(mmSRBM_STATUS); | ||
1154 | |||
1155 | if (tmp & SRBM_STATUS__IH_BUSY_MASK) | ||
1156 | reset_mask |= AMDGPU_RESET_IH; | ||
1157 | |||
1158 | if (tmp & SRBM_STATUS__SEM_BUSY_MASK) | ||
1159 | reset_mask |= AMDGPU_RESET_SEM; | ||
1160 | |||
1161 | if (tmp & SRBM_STATUS__GRBM_RQ_PENDING_MASK) | ||
1162 | reset_mask |= AMDGPU_RESET_GRBM; | ||
1163 | |||
1164 | if (tmp & SRBM_STATUS__VMC_BUSY_MASK) | ||
1165 | reset_mask |= AMDGPU_RESET_VMC; | ||
1166 | |||
1167 | if (tmp & (SRBM_STATUS__MCB_BUSY_MASK | SRBM_STATUS__MCB_NON_DISPLAY_BUSY_MASK | | ||
1168 | SRBM_STATUS__MCC_BUSY_MASK | SRBM_STATUS__MCD_BUSY_MASK)) | ||
1169 | reset_mask |= AMDGPU_RESET_MC; | ||
1170 | |||
1171 | if (amdgpu_display_is_display_hung(adev)) | ||
1172 | reset_mask |= AMDGPU_RESET_DISPLAY; | ||
1173 | |||
1174 | /* Skip MC reset as it's mostly likely not hung, just busy */ | ||
1175 | if (reset_mask & AMDGPU_RESET_MC) { | ||
1176 | DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); | ||
1177 | reset_mask &= ~AMDGPU_RESET_MC; | ||
1178 | } | ||
1179 | |||
1180 | return reset_mask; | ||
1181 | } | ||
1182 | |||
1183 | /** | ||
1184 | * cik_gpu_soft_reset - soft reset GPU | ||
1185 | * | ||
1186 | * @adev: amdgpu_device pointer | ||
1187 | * @reset_mask: mask of which blocks to reset | ||
1188 | * | ||
1189 | * Soft reset the blocks specified in @reset_mask. | ||
1190 | */ | ||
1191 | static void cik_gpu_soft_reset(struct amdgpu_device *adev, u32 reset_mask) | ||
1192 | { | ||
1193 | struct amdgpu_mode_mc_save save; | ||
1194 | u32 grbm_soft_reset = 0, srbm_soft_reset = 0; | ||
1195 | u32 tmp; | ||
1196 | |||
1197 | if (reset_mask == 0) | ||
1198 | return; | ||
1199 | |||
1200 | dev_info(adev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
1201 | |||
1202 | cik_print_gpu_status_regs(adev); | ||
1203 | dev_info(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1204 | RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_ADDR)); | ||
1205 | dev_info(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1206 | RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS)); | ||
1207 | |||
1208 | /* disable CG/PG */ | ||
1209 | |||
1210 | /* stop the rlc */ | ||
1211 | gfx_v7_0_rlc_stop(adev); | ||
1212 | |||
1213 | /* Disable GFX parsing/prefetching */ | ||
1214 | WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK); | ||
1215 | |||
1216 | /* Disable MEC parsing/prefetching */ | ||
1217 | WREG32(mmCP_MEC_CNTL, CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK); | ||
1218 | |||
1219 | if (reset_mask & AMDGPU_RESET_DMA) { | ||
1220 | /* sdma0 */ | ||
1221 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); | ||
1222 | tmp |= SDMA0_F32_CNTL__HALT_MASK; | ||
1223 | WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); | ||
1224 | } | ||
1225 | if (reset_mask & AMDGPU_RESET_DMA1) { | ||
1226 | /* sdma1 */ | ||
1227 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); | ||
1228 | tmp |= SDMA0_F32_CNTL__HALT_MASK; | ||
1229 | WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); | ||
1230 | } | ||
1231 | |||
1232 | gmc_v7_0_mc_stop(adev, &save); | ||
1233 | if (amdgpu_asic_wait_for_mc_idle(adev)) { | ||
1234 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); | ||
1235 | } | ||
1236 | |||
1237 | if (reset_mask & (AMDGPU_RESET_GFX | AMDGPU_RESET_COMPUTE | AMDGPU_RESET_CP)) | ||
1238 | grbm_soft_reset = GRBM_SOFT_RESET__SOFT_RESET_CP_MASK | | ||
1239 | GRBM_SOFT_RESET__SOFT_RESET_GFX_MASK; | ||
1240 | |||
1241 | if (reset_mask & AMDGPU_RESET_CP) { | ||
1242 | grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_CP_MASK; | ||
1243 | |||
1244 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_GRBM_MASK; | ||
1245 | } | ||
1246 | |||
1247 | if (reset_mask & AMDGPU_RESET_DMA) | ||
1248 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; | ||
1249 | |||
1250 | if (reset_mask & AMDGPU_RESET_DMA1) | ||
1251 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; | ||
1252 | |||
1253 | if (reset_mask & AMDGPU_RESET_DISPLAY) | ||
1254 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK; | ||
1255 | |||
1256 | if (reset_mask & AMDGPU_RESET_RLC) | ||
1257 | grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_RLC_MASK; | ||
1258 | |||
1259 | if (reset_mask & AMDGPU_RESET_SEM) | ||
1260 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SEM_MASK; | ||
1261 | |||
1262 | if (reset_mask & AMDGPU_RESET_IH) | ||
1263 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_IH_MASK; | ||
1264 | |||
1265 | if (reset_mask & AMDGPU_RESET_GRBM) | ||
1266 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_GRBM_MASK; | ||
1267 | |||
1268 | if (reset_mask & AMDGPU_RESET_VMC) | ||
1269 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_VMC_MASK; | ||
1270 | |||
1271 | if (!(adev->flags & AMD_IS_APU)) { | ||
1272 | if (reset_mask & AMDGPU_RESET_MC) | ||
1273 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_MC_MASK; | ||
1274 | } | ||
1275 | |||
1276 | if (grbm_soft_reset) { | ||
1277 | tmp = RREG32(mmGRBM_SOFT_RESET); | ||
1278 | tmp |= grbm_soft_reset; | ||
1279 | dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); | ||
1280 | WREG32(mmGRBM_SOFT_RESET, tmp); | ||
1281 | tmp = RREG32(mmGRBM_SOFT_RESET); | ||
1282 | |||
1283 | udelay(50); | ||
1284 | |||
1285 | tmp &= ~grbm_soft_reset; | ||
1286 | WREG32(mmGRBM_SOFT_RESET, tmp); | ||
1287 | tmp = RREG32(mmGRBM_SOFT_RESET); | ||
1288 | } | ||
1289 | |||
1290 | if (srbm_soft_reset) { | ||
1291 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
1292 | tmp |= srbm_soft_reset; | ||
1293 | dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); | ||
1294 | WREG32(mmSRBM_SOFT_RESET, tmp); | ||
1295 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
1296 | |||
1297 | udelay(50); | ||
1298 | |||
1299 | tmp &= ~srbm_soft_reset; | ||
1300 | WREG32(mmSRBM_SOFT_RESET, tmp); | ||
1301 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
1302 | } | ||
1303 | |||
1304 | /* Wait a little for things to settle down */ | ||
1305 | udelay(50); | ||
1306 | |||
1307 | gmc_v7_0_mc_resume(adev, &save); | ||
1308 | udelay(50); | ||
1309 | |||
1310 | cik_print_gpu_status_regs(adev); | ||
1311 | } | ||
1312 | |||
1313 | struct kv_reset_save_regs { | 1062 | struct kv_reset_save_regs { |
1314 | u32 gmcon_reng_execute; | 1063 | u32 gmcon_reng_execute; |
1315 | u32 gmcon_misc; | 1064 | u32 gmcon_misc; |
@@ -1405,45 +1154,11 @@ static void kv_restore_regs_for_reset(struct amdgpu_device *adev, | |||
1405 | 1154 | ||
1406 | static void cik_gpu_pci_config_reset(struct amdgpu_device *adev) | 1155 | static void cik_gpu_pci_config_reset(struct amdgpu_device *adev) |
1407 | { | 1156 | { |
1408 | struct amdgpu_mode_mc_save save; | ||
1409 | struct kv_reset_save_regs kv_save = { 0 }; | 1157 | struct kv_reset_save_regs kv_save = { 0 }; |
1410 | u32 tmp, i; | 1158 | u32 i; |
1411 | 1159 | ||
1412 | dev_info(adev->dev, "GPU pci config reset\n"); | 1160 | dev_info(adev->dev, "GPU pci config reset\n"); |
1413 | 1161 | ||
1414 | /* disable dpm? */ | ||
1415 | |||
1416 | /* disable cg/pg */ | ||
1417 | |||
1418 | /* Disable GFX parsing/prefetching */ | ||
1419 | WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | | ||
1420 | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK); | ||
1421 | |||
1422 | /* Disable MEC parsing/prefetching */ | ||
1423 | WREG32(mmCP_MEC_CNTL, | ||
1424 | CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK); | ||
1425 | |||
1426 | /* sdma0 */ | ||
1427 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); | ||
1428 | tmp |= SDMA0_F32_CNTL__HALT_MASK; | ||
1429 | WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); | ||
1430 | /* sdma1 */ | ||
1431 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); | ||
1432 | tmp |= SDMA0_F32_CNTL__HALT_MASK; | ||
1433 | WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); | ||
1434 | /* XXX other engines? */ | ||
1435 | |||
1436 | /* halt the rlc, disable cp internal ints */ | ||
1437 | gfx_v7_0_rlc_stop(adev); | ||
1438 | |||
1439 | udelay(50); | ||
1440 | |||
1441 | /* disable mem access */ | ||
1442 | gmc_v7_0_mc_stop(adev, &save); | ||
1443 | if (amdgpu_asic_wait_for_mc_idle(adev)) { | ||
1444 | dev_warn(adev->dev, "Wait for MC idle timed out !\n"); | ||
1445 | } | ||
1446 | |||
1447 | if (adev->flags & AMD_IS_APU) | 1162 | if (adev->flags & AMD_IS_APU) |
1448 | kv_save_regs_for_reset(adev, &kv_save); | 1163 | kv_save_regs_for_reset(adev, &kv_save); |
1449 | 1164 | ||
@@ -1489,26 +1204,11 @@ static void cik_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hu | |||
1489 | */ | 1204 | */ |
1490 | static int cik_asic_reset(struct amdgpu_device *adev) | 1205 | static int cik_asic_reset(struct amdgpu_device *adev) |
1491 | { | 1206 | { |
1492 | u32 reset_mask; | 1207 | cik_set_bios_scratch_engine_hung(adev, true); |
1493 | |||
1494 | reset_mask = amdgpu_cik_gpu_check_soft_reset(adev); | ||
1495 | |||
1496 | if (reset_mask) | ||
1497 | cik_set_bios_scratch_engine_hung(adev, true); | ||
1498 | |||
1499 | /* try soft reset */ | ||
1500 | cik_gpu_soft_reset(adev, reset_mask); | ||
1501 | |||
1502 | reset_mask = amdgpu_cik_gpu_check_soft_reset(adev); | ||
1503 | |||
1504 | /* try pci config reset */ | ||
1505 | if (reset_mask && amdgpu_hard_reset) | ||
1506 | cik_gpu_pci_config_reset(adev); | ||
1507 | 1208 | ||
1508 | reset_mask = amdgpu_cik_gpu_check_soft_reset(adev); | 1209 | cik_gpu_pci_config_reset(adev); |
1509 | 1210 | ||
1510 | if (!reset_mask) | 1211 | cik_set_bios_scratch_engine_hung(adev, false); |
1511 | cik_set_bios_scratch_engine_hung(adev, false); | ||
1512 | 1212 | ||
1513 | return 0; | 1213 | return 0; |
1514 | } | 1214 | } |