diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-18 11:05:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-18 11:05:29 -0400 |
commit | 37c1e28931333c4b838d1c8db5cdd8d75165dc6b (patch) | |
tree | 54c0123816857a1cddd9b8b759759eb1ac8dc870 /drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |
parent | 14155cafeadda946376260e2ad5d39a0528a332f (diff) | |
parent | fa860a1751e388385a7f249dd3f24a6c76db0ba9 (diff) |
Merge tag 'drm-fixes-for-v4.9-rc2' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie:
"Just had a couple of amdgpu fixes and one core fix I wanted to get out
early to fix some regressions.
I'm sure I'll have more stuff this week for -rc2"
* tag 'drm-fixes-for-v4.9-rc2' of git://people.freedesktop.org/~airlied/linux: (22 commits)
drm: Print device information again in debugfs
drm/amd/powerplay: fix bug stop dpm can't work on Vi.
drm/amd/powerplay: notify smu no display by default.
drm/amdgpu/dpm: implement thermal sensor for CZ/ST
drm/amdgpu/powerplay: implement thermal sensor for CZ/ST
drm/amdgpu: disable smu hw first on tear down
drm/amdgpu: fix amdgpu_need_full_reset (v2)
drm/amdgpu/si_dpm: Limit clocks on HD86xx part
drm/amd/powerplay: fix static checker warnings in smu7_hwmgr.c
drm/amdgpu: potential NULL dereference in debugfs code
drm/amd/powerplay: fix static checker warnings in smu7_hwmgr.c
drm/amd/powerplay: fix static checker warnings in iceland_smc.c
drm/radeon: change vblank_time's calculation method to reduce computational error.
drm/amdgpu: change vblank_time's calculation method to reduce computational error.
drm/amdgpu: clarify UVD/VCE special handling for CG
drm/amd/amdgpu: enable clockgating only after late init
drm/radeon: allow TA_CS_BC_BASE_ADDR on SI
drm/amdgpu: initialize the context reset_counter in amdgpu_ctx_init
drm/amdgpu/gfx8: fix CGCG_CGLS handling
drm/radeon: fix modeset tear down code
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7dbe85d67d26..b4f4a9239069 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -1408,16 +1408,6 @@ static int amdgpu_late_init(struct amdgpu_device *adev) | |||
1408 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1408 | for (i = 0; i < adev->num_ip_blocks; i++) { |
1409 | if (!adev->ip_block_status[i].valid) | 1409 | if (!adev->ip_block_status[i].valid) |
1410 | continue; | 1410 | continue; |
1411 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_UVD || | ||
1412 | adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_VCE) | ||
1413 | continue; | ||
1414 | /* enable clockgating to save power */ | ||
1415 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | ||
1416 | AMD_CG_STATE_GATE); | ||
1417 | if (r) { | ||
1418 | DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r); | ||
1419 | return r; | ||
1420 | } | ||
1421 | if (adev->ip_blocks[i].funcs->late_init) { | 1411 | if (adev->ip_blocks[i].funcs->late_init) { |
1422 | r = adev->ip_blocks[i].funcs->late_init((void *)adev); | 1412 | r = adev->ip_blocks[i].funcs->late_init((void *)adev); |
1423 | if (r) { | 1413 | if (r) { |
@@ -1426,6 +1416,18 @@ static int amdgpu_late_init(struct amdgpu_device *adev) | |||
1426 | } | 1416 | } |
1427 | adev->ip_block_status[i].late_initialized = true; | 1417 | adev->ip_block_status[i].late_initialized = true; |
1428 | } | 1418 | } |
1419 | /* skip CG for VCE/UVD, it's handled specially */ | ||
1420 | if (adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_UVD && | ||
1421 | adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_VCE) { | ||
1422 | /* enable clockgating to save power */ | ||
1423 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | ||
1424 | AMD_CG_STATE_GATE); | ||
1425 | if (r) { | ||
1426 | DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n", | ||
1427 | adev->ip_blocks[i].funcs->name, r); | ||
1428 | return r; | ||
1429 | } | ||
1430 | } | ||
1429 | } | 1431 | } |
1430 | 1432 | ||
1431 | return 0; | 1433 | return 0; |
@@ -1435,6 +1437,30 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
1435 | { | 1437 | { |
1436 | int i, r; | 1438 | int i, r; |
1437 | 1439 | ||
1440 | /* need to disable SMC first */ | ||
1441 | for (i = 0; i < adev->num_ip_blocks; i++) { | ||
1442 | if (!adev->ip_block_status[i].hw) | ||
1443 | continue; | ||
1444 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) { | ||
1445 | /* ungate blocks before hw fini so that we can shutdown the blocks safely */ | ||
1446 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | ||
1447 | AMD_CG_STATE_UNGATE); | ||
1448 | if (r) { | ||
1449 | DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n", | ||
1450 | adev->ip_blocks[i].funcs->name, r); | ||
1451 | return r; | ||
1452 | } | ||
1453 | r = adev->ip_blocks[i].funcs->hw_fini((void *)adev); | ||
1454 | /* XXX handle errors */ | ||
1455 | if (r) { | ||
1456 | DRM_DEBUG("hw_fini of IP block <%s> failed %d\n", | ||
1457 | adev->ip_blocks[i].funcs->name, r); | ||
1458 | } | ||
1459 | adev->ip_block_status[i].hw = false; | ||
1460 | break; | ||
1461 | } | ||
1462 | } | ||
1463 | |||
1438 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1464 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
1439 | if (!adev->ip_block_status[i].hw) | 1465 | if (!adev->ip_block_status[i].hw) |
1440 | continue; | 1466 | continue; |
@@ -2073,7 +2099,8 @@ static bool amdgpu_check_soft_reset(struct amdgpu_device *adev) | |||
2073 | if (!adev->ip_block_status[i].valid) | 2099 | if (!adev->ip_block_status[i].valid) |
2074 | continue; | 2100 | continue; |
2075 | if (adev->ip_blocks[i].funcs->check_soft_reset) | 2101 | if (adev->ip_blocks[i].funcs->check_soft_reset) |
2076 | adev->ip_blocks[i].funcs->check_soft_reset(adev); | 2102 | adev->ip_block_status[i].hang = |
2103 | adev->ip_blocks[i].funcs->check_soft_reset(adev); | ||
2077 | if (adev->ip_block_status[i].hang) { | 2104 | if (adev->ip_block_status[i].hang) { |
2078 | DRM_INFO("IP block:%d is hang!\n", i); | 2105 | DRM_INFO("IP block:%d is hang!\n", i); |
2079 | asic_hang = true; | 2106 | asic_hang = true; |
@@ -2102,12 +2129,20 @@ static int amdgpu_pre_soft_reset(struct amdgpu_device *adev) | |||
2102 | 2129 | ||
2103 | static bool amdgpu_need_full_reset(struct amdgpu_device *adev) | 2130 | static bool amdgpu_need_full_reset(struct amdgpu_device *adev) |
2104 | { | 2131 | { |
2105 | if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang || | 2132 | int i; |
2106 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang || | 2133 | |
2107 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang || | 2134 | for (i = 0; i < adev->num_ip_blocks; i++) { |
2108 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) { | 2135 | if (!adev->ip_block_status[i].valid) |
2109 | DRM_INFO("Some block need full reset!\n"); | 2136 | continue; |
2110 | return true; | 2137 | if ((adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) || |
2138 | (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) || | ||
2139 | (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_ACP) || | ||
2140 | (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_DCE)) { | ||
2141 | if (adev->ip_block_status[i].hang) { | ||
2142 | DRM_INFO("Some block need full reset!\n"); | ||
2143 | return true; | ||
2144 | } | ||
2145 | } | ||
2111 | } | 2146 | } |
2112 | return false; | 2147 | return false; |
2113 | } | 2148 | } |