diff options
author | Chunming Zhou <David1.Zhou@amd.com> | 2016-07-12 22:28:56 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-08-08 11:32:07 -0400 |
commit | e702a68051b174e87df62bbc0204809b5c1ba3e5 (patch) | |
tree | f976f658720501ec9198a858deff050eb067a834 | |
parent | e4ae0fc3363191f31fb9627fff9f88d43523aac7 (diff) |
drm/amdgpu: implement sdma3 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 | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 80 |
3 files changed, 68 insertions, 14 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index b6e8e7a825f8..17600b477cf9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1733,6 +1733,7 @@ struct amdgpu_sdma { | |||
1733 | struct amdgpu_irq_src trap_irq; | 1733 | struct amdgpu_irq_src trap_irq; |
1734 | struct amdgpu_irq_src illegal_inst_irq; | 1734 | struct amdgpu_irq_src illegal_inst_irq; |
1735 | int num_instances; | 1735 | int num_instances; |
1736 | uint32_t srbm_soft_reset; | ||
1736 | }; | 1737 | }; |
1737 | 1738 | ||
1738 | /* | 1739 | /* |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 1e553663e47d..47f29f9e6df5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -1978,7 +1978,6 @@ static bool amdgpu_need_full_reset(struct amdgpu_device *adev) | |||
1978 | if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang || | 1978 | if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang || |
1979 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang || | 1979 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang || |
1980 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang || | 1980 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang || |
1981 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang || | ||
1982 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang || | 1981 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang || |
1983 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang || | 1982 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang || |
1984 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang || | 1983 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang || |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 653ce5ed55ae..3a63a4fcf807 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
@@ -1320,28 +1320,79 @@ static int sdma_v3_0_wait_for_idle(void *handle) | |||
1320 | return -ETIMEDOUT; | 1320 | return -ETIMEDOUT; |
1321 | } | 1321 | } |
1322 | 1322 | ||
1323 | static int sdma_v3_0_soft_reset(void *handle) | 1323 | static int sdma_v3_0_check_soft_reset(void *handle) |
1324 | { | 1324 | { |
1325 | u32 srbm_soft_reset = 0; | ||
1326 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1325 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1326 | u32 srbm_soft_reset = 0; | ||
1327 | u32 tmp = RREG32(mmSRBM_STATUS2); | 1327 | u32 tmp = RREG32(mmSRBM_STATUS2); |
1328 | 1328 | ||
1329 | if (tmp & SRBM_STATUS2__SDMA_BUSY_MASK) { | 1329 | if ((tmp & SRBM_STATUS2__SDMA_BUSY_MASK) || |
1330 | /* sdma0 */ | 1330 | (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK)) { |
1331 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); | ||
1332 | tmp = REG_SET_FIELD(tmp, SDMA0_F32_CNTL, HALT, 0); | ||
1333 | WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); | ||
1334 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; | 1331 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; |
1335 | } | ||
1336 | if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) { | ||
1337 | /* sdma1 */ | ||
1338 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); | ||
1339 | tmp = REG_SET_FIELD(tmp, SDMA0_F32_CNTL, HALT, 0); | ||
1340 | WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); | ||
1341 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; | 1332 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; |
1342 | } | 1333 | } |
1343 | 1334 | ||
1344 | if (srbm_soft_reset) { | 1335 | if (srbm_soft_reset) { |
1336 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = true; | ||
1337 | adev->sdma.srbm_soft_reset = srbm_soft_reset; | ||
1338 | } else { | ||
1339 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = false; | ||
1340 | adev->sdma.srbm_soft_reset = 0; | ||
1341 | } | ||
1342 | |||
1343 | return 0; | ||
1344 | } | ||
1345 | |||
1346 | static int sdma_v3_0_pre_soft_reset(void *handle) | ||
1347 | { | ||
1348 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1349 | u32 srbm_soft_reset = 0; | ||
1350 | |||
1351 | if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang) | ||
1352 | return 0; | ||
1353 | |||
1354 | srbm_soft_reset = adev->sdma.srbm_soft_reset; | ||
1355 | |||
1356 | if (REG_GET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA) || | ||
1357 | REG_GET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA1)) { | ||
1358 | sdma_v3_0_ctx_switch_enable(adev, false); | ||
1359 | sdma_v3_0_enable(adev, false); | ||
1360 | } | ||
1361 | |||
1362 | return 0; | ||
1363 | } | ||
1364 | |||
1365 | static int sdma_v3_0_post_soft_reset(void *handle) | ||
1366 | { | ||
1367 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1368 | u32 srbm_soft_reset = 0; | ||
1369 | |||
1370 | if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang) | ||
1371 | return 0; | ||
1372 | |||
1373 | srbm_soft_reset = adev->sdma.srbm_soft_reset; | ||
1374 | |||
1375 | if (REG_GET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA) || | ||
1376 | REG_GET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA1)) { | ||
1377 | sdma_v3_0_gfx_resume(adev); | ||
1378 | sdma_v3_0_rlc_resume(adev); | ||
1379 | } | ||
1380 | |||
1381 | return 0; | ||
1382 | } | ||
1383 | |||
1384 | static int sdma_v3_0_soft_reset(void *handle) | ||
1385 | { | ||
1386 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1387 | u32 srbm_soft_reset = 0; | ||
1388 | u32 tmp; | ||
1389 | |||
1390 | if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang) | ||
1391 | return 0; | ||
1392 | |||
1393 | srbm_soft_reset = adev->sdma.srbm_soft_reset; | ||
1394 | |||
1395 | if (srbm_soft_reset) { | ||
1345 | tmp = RREG32(mmSRBM_SOFT_RESET); | 1396 | tmp = RREG32(mmSRBM_SOFT_RESET); |
1346 | tmp |= srbm_soft_reset; | 1397 | tmp |= srbm_soft_reset; |
1347 | dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); | 1398 | dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); |
@@ -1559,6 +1610,9 @@ const struct amd_ip_funcs sdma_v3_0_ip_funcs = { | |||
1559 | .resume = sdma_v3_0_resume, | 1610 | .resume = sdma_v3_0_resume, |
1560 | .is_idle = sdma_v3_0_is_idle, | 1611 | .is_idle = sdma_v3_0_is_idle, |
1561 | .wait_for_idle = sdma_v3_0_wait_for_idle, | 1612 | .wait_for_idle = sdma_v3_0_wait_for_idle, |
1613 | .check_soft_reset = sdma_v3_0_check_soft_reset, | ||
1614 | .pre_soft_reset = sdma_v3_0_pre_soft_reset, | ||
1615 | .post_soft_reset = sdma_v3_0_post_soft_reset, | ||
1562 | .soft_reset = sdma_v3_0_soft_reset, | 1616 | .soft_reset = sdma_v3_0_soft_reset, |
1563 | .set_clockgating_state = sdma_v3_0_set_clockgating_state, | 1617 | .set_clockgating_state = sdma_v3_0_set_clockgating_state, |
1564 | .set_powergating_state = sdma_v3_0_set_powergating_state, | 1618 | .set_powergating_state = sdma_v3_0_set_powergating_state, |