Commit 42332905 authored by Alex Deucher's avatar Alex Deucher Committed by Christian König

drm/radeon: add vce dpm support for KV/KB

TODO: plug in cik_vce_suspend()/resume() so we can enable
vce powergating. See XXX in code.
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ee35b002
...@@ -1338,13 +1338,11 @@ static int kv_enable_uvd_dpm(struct radeon_device *rdev, bool enable) ...@@ -1338,13 +1338,11 @@ static int kv_enable_uvd_dpm(struct radeon_device *rdev, bool enable)
PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable); PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable);
} }
#if 0
static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable) static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable)
{ {
return kv_notify_message_to_smu(rdev, enable ? return kv_notify_message_to_smu(rdev, enable ?
PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable); PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable);
} }
#endif
static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable) static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable)
{ {
...@@ -1389,7 +1387,6 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate) ...@@ -1389,7 +1387,6 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate)
return kv_enable_uvd_dpm(rdev, !gate); return kv_enable_uvd_dpm(rdev, !gate);
} }
#if 0
static u8 kv_get_vce_boot_level(struct radeon_device *rdev) static u8 kv_get_vce_boot_level(struct radeon_device *rdev)
{ {
u8 i; u8 i;
...@@ -1414,6 +1411,8 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, ...@@ -1414,6 +1411,8 @@ static int kv_update_vce_dpm(struct radeon_device *rdev,
int ret; int ret;
if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) { if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) {
kv_dpm_powergate_vce(rdev, false);
/* XXX cik_vce_resume(); */
if (pi->caps_stable_p_state) if (pi->caps_stable_p_state)
pi->vce_boot_level = table->count - 1; pi->vce_boot_level = table->count - 1;
else else
...@@ -1436,11 +1435,12 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, ...@@ -1436,11 +1435,12 @@ static int kv_update_vce_dpm(struct radeon_device *rdev,
kv_enable_vce_dpm(rdev, true); kv_enable_vce_dpm(rdev, true);
} else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) { } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) {
kv_enable_vce_dpm(rdev, false); kv_enable_vce_dpm(rdev, false);
/* XXX cik_vce_suspend(); */
kv_dpm_powergate_vce(rdev, true);
} }
return 0; return 0;
} }
#endif
static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate) static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate)
{ {
...@@ -1768,7 +1768,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) ...@@ -1768,7 +1768,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
{ {
struct kv_power_info *pi = kv_get_pi(rdev); struct kv_power_info *pi = kv_get_pi(rdev);
struct radeon_ps *new_ps = &pi->requested_rps; struct radeon_ps *new_ps = &pi->requested_rps;
/*struct radeon_ps *old_ps = &pi->current_rps;*/ struct radeon_ps *old_ps = &pi->current_rps;
int ret; int ret;
if (pi->bapm_enable) { if (pi->bapm_enable) {
...@@ -1798,13 +1798,12 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) ...@@ -1798,13 +1798,12 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
kv_set_enabled_levels(rdev); kv_set_enabled_levels(rdev);
kv_force_lowest_valid(rdev); kv_force_lowest_valid(rdev);
kv_unforce_levels(rdev); kv_unforce_levels(rdev);
#if 0
ret = kv_update_vce_dpm(rdev, new_ps, old_ps); ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
if (ret) { if (ret) {
DRM_ERROR("kv_update_vce_dpm failed\n"); DRM_ERROR("kv_update_vce_dpm failed\n");
return ret; return ret;
} }
#endif
kv_update_sclk_t(rdev); kv_update_sclk_t(rdev);
} }
} else { } else {
...@@ -1823,13 +1822,11 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) ...@@ -1823,13 +1822,11 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
kv_program_nbps_index_settings(rdev, new_ps); kv_program_nbps_index_settings(rdev, new_ps);
kv_freeze_sclk_dpm(rdev, false); kv_freeze_sclk_dpm(rdev, false);
kv_set_enabled_levels(rdev); kv_set_enabled_levels(rdev);
#if 0
ret = kv_update_vce_dpm(rdev, new_ps, old_ps); ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
if (ret) { if (ret) {
DRM_ERROR("kv_update_vce_dpm failed\n"); DRM_ERROR("kv_update_vce_dpm failed\n");
return ret; return ret;
} }
#endif
kv_update_acp_boot_level(rdev); kv_update_acp_boot_level(rdev);
kv_update_sclk_t(rdev); kv_update_sclk_t(rdev);
kv_enable_nb_dpm(rdev); kv_enable_nb_dpm(rdev);
...@@ -2037,6 +2034,14 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, ...@@ -2037,6 +2034,14 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
struct radeon_clock_and_voltage_limits *max_limits = struct radeon_clock_and_voltage_limits *max_limits =
&rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
if (new_rps->vce_active) {
new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk;
} else {
new_rps->evclk = 0;
new_rps->ecclk = 0;
}
mclk = max_limits->mclk; mclk = max_limits->mclk;
sclk = min_sclk; sclk = min_sclk;
...@@ -2056,6 +2061,11 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, ...@@ -2056,6 +2061,11 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
sclk = stable_p_state_sclk; sclk = stable_p_state_sclk;
} }
if (new_rps->vce_active) {
if (sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk)
sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk;
}
ps->need_dfs_bypass = true; ps->need_dfs_bypass = true;
for (i = 0; i < ps->num_levels; i++) { for (i = 0; i < ps->num_levels; i++) {
...@@ -2092,7 +2102,8 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, ...@@ -2092,7 +2102,8 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
} }
} }
pi->video_start = new_rps->dclk || new_rps->vclk; pi->video_start = new_rps->dclk || new_rps->vclk ||
new_rps->evclk || new_rps->ecclk;
if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)
...@@ -2574,6 +2585,19 @@ static int kv_parse_power_table(struct radeon_device *rdev) ...@@ -2574,6 +2585,19 @@ static int kv_parse_power_table(struct radeon_device *rdev)
power_state_offset += 2 + power_state->v2.ucNumDPMLevels; power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
} }
rdev->pm.dpm.num_ps = state_array->ucNumEntries; rdev->pm.dpm.num_ps = state_array->ucNumEntries;
/* fill in the vce power states */
for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
u32 sclk;
clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
clock_info = (union pplib_clock_info *)
&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
sclk |= clock_info->sumo.ucEngineClockHigh << 16;
rdev->pm.dpm.vce_states[i].sclk = sclk;
rdev->pm.dpm.vce_states[i].mclk = 0;
}
return 0; return 0;
} }
...@@ -2624,7 +2648,7 @@ int kv_dpm_init(struct radeon_device *rdev) ...@@ -2624,7 +2648,7 @@ int kv_dpm_init(struct radeon_device *rdev)
pi->caps_fps = false; /* true? */ pi->caps_fps = false; /* true? */
pi->caps_uvd_pg = true; 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; /* XXX true */
pi->caps_samu_pg = false; pi->caps_samu_pg = false;
pi->caps_acp_pg = false; pi->caps_acp_pg = false;
pi->caps_stable_p_state = false; pi->caps_stable_p_state = false;
......
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