Commit 77df508a authored by Alex Deucher's avatar Alex Deucher

drm/radeon/dpm: implement UVD powergating for KB/KV

Powergate the UVD block when not in use to save power.
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5e884f60
...@@ -69,7 +69,7 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev); ...@@ -69,7 +69,7 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev);
static void cik_program_aspm(struct radeon_device *rdev); static void cik_program_aspm(struct radeon_device *rdev);
static void cik_init_pg(struct radeon_device *rdev); static void cik_init_pg(struct radeon_device *rdev);
static void cik_init_cg(struct radeon_device *rdev); static void cik_init_cg(struct radeon_device *rdev);
static void cik_uvd_resume(struct radeon_device *rdev); void cik_uvd_resume(struct radeon_device *rdev);
/* get temperature in millidegrees */ /* get temperature in millidegrees */
int ci_get_temp(struct radeon_device *rdev) 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,7 +8600,7 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
return r; return r;
} }
static void cik_uvd_resume(struct radeon_device *rdev) void cik_uvd_resume(struct radeon_device *rdev)
{ {
uint64_t addr; uint64_t addr;
uint32_t size; uint32_t size;
......
...@@ -49,7 +49,7 @@ static int kv_set_thermal_temperature_range(struct radeon_device *rdev, ...@@ -49,7 +49,7 @@ static int kv_set_thermal_temperature_range(struct radeon_device *rdev,
int min_temp, int max_temp); int min_temp, int max_temp);
static int kv_init_fps_limits(struct radeon_device *rdev); static int kv_init_fps_limits(struct radeon_device *rdev);
static void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate); void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate);
static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate); static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate);
static void kv_dpm_powergate_samu(struct radeon_device *rdev, bool gate); static void kv_dpm_powergate_samu(struct radeon_device *rdev, bool gate);
static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate); 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,6 +59,10 @@ extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
extern void cik_update_cg(struct radeon_device *rdev, extern void cik_update_cg(struct radeon_device *rdev,
u32 block, bool enable); u32 block, bool enable);
extern void cik_uvd_resume(struct radeon_device *rdev);
extern int r600_uvd_init(struct radeon_device *rdev, bool ring_test);
extern void r600_do_uvd_stop(struct radeon_device *rdev);
static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] = static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] =
{ {
{ 0, 4, 1 }, { 0, 4, 1 },
...@@ -1201,6 +1205,7 @@ int kv_dpm_enable(struct radeon_device *rdev) ...@@ -1201,6 +1205,7 @@ int kv_dpm_enable(struct radeon_device *rdev)
kv_dpm_powergate_acp(rdev, true); kv_dpm_powergate_acp(rdev, true);
kv_dpm_powergate_samu(rdev, true); kv_dpm_powergate_samu(rdev, true);
kv_dpm_powergate_vce(rdev, true); kv_dpm_powergate_vce(rdev, true);
kv_dpm_powergate_uvd(rdev, true);
kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps); kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
...@@ -1458,7 +1463,7 @@ static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate) ...@@ -1458,7 +1463,7 @@ static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate)
return kv_enable_acp_dpm(rdev, !gate); return kv_enable_acp_dpm(rdev, !gate);
} }
static void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate) void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate)
{ {
struct kv_power_info *pi = kv_get_pi(rdev); struct kv_power_info *pi = kv_get_pi(rdev);
...@@ -1468,13 +1473,18 @@ static void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate) ...@@ -1468,13 +1473,18 @@ static void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate)
pi->uvd_power_gated = gate; pi->uvd_power_gated = gate;
if (gate) { if (gate) {
kv_update_uvd_dpm(rdev, true); r600_do_uvd_stop(rdev);
cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
kv_update_uvd_dpm(rdev, gate);
if (pi->caps_uvd_pg) if (pi->caps_uvd_pg)
kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerOFF); kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerOFF);
} else { } else {
if (pi->caps_uvd_pg) if (pi->caps_uvd_pg)
kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerON); kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerON);
kv_update_uvd_dpm(rdev, false); cik_uvd_resume(rdev);
r600_uvd_init(rdev, false);
cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
kv_update_uvd_dpm(rdev, gate);
} }
} }
...@@ -1714,7 +1724,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) ...@@ -1714,7 +1724,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
return ret; return ret;
} }
#endif #endif
kv_update_uvd_dpm(rdev, false);
kv_update_sclk_t(rdev); kv_update_sclk_t(rdev);
} }
} else { } else {
...@@ -1740,7 +1749,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) ...@@ -1740,7 +1749,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
return ret; return ret;
} }
#endif #endif
kv_update_uvd_dpm(rdev, false);
kv_update_sclk_t(rdev); kv_update_sclk_t(rdev);
kv_enable_nb_dpm(rdev); kv_enable_nb_dpm(rdev);
} }
...@@ -2502,7 +2510,7 @@ int kv_dpm_init(struct radeon_device *rdev) ...@@ -2502,7 +2510,7 @@ int kv_dpm_init(struct radeon_device *rdev)
pi->voltage_drop_t = 0; pi->voltage_drop_t = 0;
pi->caps_sclk_throttle_low_notification = false; pi->caps_sclk_throttle_low_notification = false;
pi->caps_fps = false; /* true? */ pi->caps_fps = false; /* true? */
pi->caps_uvd_pg = false; /* XXX */ pi->caps_uvd_pg = true;
pi->caps_uvd_dpm = true; pi->caps_uvd_dpm = true;
pi->caps_vce_pg = false; pi->caps_vce_pg = false;
pi->caps_samu_pg = false; pi->caps_samu_pg = false;
......
...@@ -2642,6 +2642,7 @@ static struct radeon_asic kv_asic = { ...@@ -2642,6 +2642,7 @@ static struct radeon_asic kv_asic = {
.print_power_state = &kv_dpm_print_power_state, .print_power_state = &kv_dpm_print_power_state,
.debugfs_print_current_performance_level = &kv_dpm_debugfs_print_current_performance_level, .debugfs_print_current_performance_level = &kv_dpm_debugfs_print_current_performance_level,
.force_performance_level = &kv_dpm_force_performance_level, .force_performance_level = &kv_dpm_force_performance_level,
.powergate_uvd = &kv_dpm_powergate_uvd,
}, },
.pflip = { .pflip = {
.pre_page_flip = &evergreen_pre_page_flip, .pre_page_flip = &evergreen_pre_page_flip,
......
...@@ -784,5 +784,6 @@ void kv_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, ...@@ -784,5 +784,6 @@ void kv_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m); struct seq_file *m);
int kv_dpm_force_performance_level(struct radeon_device *rdev, int kv_dpm_force_performance_level(struct radeon_device *rdev,
enum radeon_dpm_forced_level level); enum radeon_dpm_forced_level level);
void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment