diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-08-09 10:02:40 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-08-30 16:30:35 -0400 |
commit | 77df508a98834d8e2fe4c7c4e1089a1ce66ccaa1 (patch) | |
tree | ae64267036d2440e0d07e5b0001d96aceb06311b /drivers/gpu/drm | |
parent | 5e884f606cdba9c599c9c9373808f272ae794088 (diff) |
drm/radeon/dpm: implement UVD powergating for KB/KV
Powergate the UVD block when not in use to save power.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/kv_dpm.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 1 |
4 files changed, 19 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 59b866aa08d9..e661aec734b2 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -69,7 +69,7 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev); | |||
69 | static void cik_program_aspm(struct radeon_device *rdev); | 69 | static void cik_program_aspm(struct radeon_device *rdev); |
70 | static void cik_init_pg(struct radeon_device *rdev); | 70 | static void cik_init_pg(struct radeon_device *rdev); |
71 | static void cik_init_cg(struct radeon_device *rdev); | 71 | static void cik_init_cg(struct radeon_device *rdev); |
72 | static void cik_uvd_resume(struct radeon_device *rdev); | 72 | void cik_uvd_resume(struct radeon_device *rdev); |
73 | 73 | ||
74 | /* get temperature in millidegrees */ | 74 | /* get temperature in millidegrees */ |
75 | int ci_get_temp(struct radeon_device *rdev) | 75 | int ci_get_temp(struct radeon_device *rdev) |
@@ -8600,7 +8600,7 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) | |||
8600 | return r; | 8600 | return r; |
8601 | } | 8601 | } |
8602 | 8602 | ||
8603 | static void cik_uvd_resume(struct radeon_device *rdev) | 8603 | void cik_uvd_resume(struct radeon_device *rdev) |
8604 | { | 8604 | { |
8605 | uint64_t addr; | 8605 | uint64_t addr; |
8606 | uint32_t size; | 8606 | uint32_t size; |
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index c26c4e3005e7..3e232a4d3f4c 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -49,7 +49,7 @@ static int kv_set_thermal_temperature_range(struct radeon_device *rdev, | |||
49 | int min_temp, int max_temp); | 49 | int min_temp, int max_temp); |
50 | static int kv_init_fps_limits(struct radeon_device *rdev); | 50 | static int kv_init_fps_limits(struct radeon_device *rdev); |
51 | 51 | ||
52 | static void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate); | 52 | void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate); |
53 | static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate); | 53 | static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate); |
54 | static void kv_dpm_powergate_samu(struct radeon_device *rdev, bool gate); | 54 | static void kv_dpm_powergate_samu(struct radeon_device *rdev, bool gate); |
55 | static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate); | 55 | static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate); |
@@ -59,6 +59,10 @@ extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev); | |||
59 | extern void cik_update_cg(struct radeon_device *rdev, | 59 | extern void cik_update_cg(struct radeon_device *rdev, |
60 | u32 block, bool enable); | 60 | u32 block, bool enable); |
61 | 61 | ||
62 | extern void cik_uvd_resume(struct radeon_device *rdev); | ||
63 | extern int r600_uvd_init(struct radeon_device *rdev, bool ring_test); | ||
64 | extern void r600_do_uvd_stop(struct radeon_device *rdev); | ||
65 | |||
62 | static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] = | 66 | static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] = |
63 | { | 67 | { |
64 | { 0, 4, 1 }, | 68 | { 0, 4, 1 }, |
@@ -1201,6 +1205,7 @@ int kv_dpm_enable(struct radeon_device *rdev) | |||
1201 | kv_dpm_powergate_acp(rdev, true); | 1205 | kv_dpm_powergate_acp(rdev, true); |
1202 | kv_dpm_powergate_samu(rdev, true); | 1206 | kv_dpm_powergate_samu(rdev, true); |
1203 | kv_dpm_powergate_vce(rdev, true); | 1207 | kv_dpm_powergate_vce(rdev, true); |
1208 | kv_dpm_powergate_uvd(rdev, true); | ||
1204 | 1209 | ||
1205 | kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps); | 1210 | kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps); |
1206 | 1211 | ||
@@ -1458,7 +1463,7 @@ static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate) | |||
1458 | return kv_enable_acp_dpm(rdev, !gate); | 1463 | return kv_enable_acp_dpm(rdev, !gate); |
1459 | } | 1464 | } |
1460 | 1465 | ||
1461 | static void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate) | 1466 | void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate) |
1462 | { | 1467 | { |
1463 | struct kv_power_info *pi = kv_get_pi(rdev); | 1468 | struct kv_power_info *pi = kv_get_pi(rdev); |
1464 | 1469 | ||
@@ -1468,13 +1473,18 @@ static void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate) | |||
1468 | pi->uvd_power_gated = gate; | 1473 | pi->uvd_power_gated = gate; |
1469 | 1474 | ||
1470 | if (gate) { | 1475 | if (gate) { |
1471 | kv_update_uvd_dpm(rdev, true); | 1476 | r600_do_uvd_stop(rdev); |
1477 | cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, false); | ||
1478 | kv_update_uvd_dpm(rdev, gate); | ||
1472 | if (pi->caps_uvd_pg) | 1479 | if (pi->caps_uvd_pg) |
1473 | kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerOFF); | 1480 | kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerOFF); |
1474 | } else { | 1481 | } else { |
1475 | if (pi->caps_uvd_pg) | 1482 | if (pi->caps_uvd_pg) |
1476 | kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerON); | 1483 | kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerON); |
1477 | kv_update_uvd_dpm(rdev, false); | 1484 | cik_uvd_resume(rdev); |
1485 | r600_uvd_init(rdev, false); | ||
1486 | cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, true); | ||
1487 | kv_update_uvd_dpm(rdev, gate); | ||
1478 | } | 1488 | } |
1479 | } | 1489 | } |
1480 | 1490 | ||
@@ -1714,7 +1724,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1714 | return ret; | 1724 | return ret; |
1715 | } | 1725 | } |
1716 | #endif | 1726 | #endif |
1717 | kv_update_uvd_dpm(rdev, false); | ||
1718 | kv_update_sclk_t(rdev); | 1727 | kv_update_sclk_t(rdev); |
1719 | } | 1728 | } |
1720 | } else { | 1729 | } else { |
@@ -1740,7 +1749,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1740 | return ret; | 1749 | return ret; |
1741 | } | 1750 | } |
1742 | #endif | 1751 | #endif |
1743 | kv_update_uvd_dpm(rdev, false); | ||
1744 | kv_update_sclk_t(rdev); | 1752 | kv_update_sclk_t(rdev); |
1745 | kv_enable_nb_dpm(rdev); | 1753 | kv_enable_nb_dpm(rdev); |
1746 | } | 1754 | } |
@@ -2502,7 +2510,7 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
2502 | pi->voltage_drop_t = 0; | 2510 | pi->voltage_drop_t = 0; |
2503 | pi->caps_sclk_throttle_low_notification = false; | 2511 | pi->caps_sclk_throttle_low_notification = false; |
2504 | pi->caps_fps = false; /* true? */ | 2512 | pi->caps_fps = false; /* true? */ |
2505 | pi->caps_uvd_pg = false; /* XXX */ | 2513 | pi->caps_uvd_pg = true; |
2506 | pi->caps_uvd_dpm = true; | 2514 | pi->caps_uvd_dpm = true; |
2507 | pi->caps_vce_pg = false; | 2515 | pi->caps_vce_pg = false; |
2508 | pi->caps_samu_pg = false; | 2516 | pi->caps_samu_pg = false; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 1dad80c0e17f..63b6aae66236 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -2642,6 +2642,7 @@ static struct radeon_asic kv_asic = { | |||
2642 | .print_power_state = &kv_dpm_print_power_state, | 2642 | .print_power_state = &kv_dpm_print_power_state, |
2643 | .debugfs_print_current_performance_level = &kv_dpm_debugfs_print_current_performance_level, | 2643 | .debugfs_print_current_performance_level = &kv_dpm_debugfs_print_current_performance_level, |
2644 | .force_performance_level = &kv_dpm_force_performance_level, | 2644 | .force_performance_level = &kv_dpm_force_performance_level, |
2645 | .powergate_uvd = &kv_dpm_powergate_uvd, | ||
2645 | }, | 2646 | }, |
2646 | .pflip = { | 2647 | .pflip = { |
2647 | .pre_page_flip = &evergreen_pre_page_flip, | 2648 | .pre_page_flip = &evergreen_pre_page_flip, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 3570817a5847..9060757e4dc1 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -784,5 +784,6 @@ void kv_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | |||
784 | struct seq_file *m); | 784 | struct seq_file *m); |
785 | int kv_dpm_force_performance_level(struct radeon_device *rdev, | 785 | int kv_dpm_force_performance_level(struct radeon_device *rdev, |
786 | enum radeon_dpm_forced_level level); | 786 | enum radeon_dpm_forced_level level); |
787 | void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate); | ||
787 | 788 | ||
788 | #endif | 789 | #endif |