[PATCH 11/15] drm/radeon: add vce dpm support for KV/KB

Christian König deathsimple at vodafone.de
Tue Feb 4 07:18:00 PST 2014


From: Alex Deucher <alexander.deucher at amd.com>

TODO: plug in cik_vce_suspend()/resume() so we can enable
vce powergating. See XXX in code.

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/kv_dpm.c | 46 +++++++++++++++++++++++++++++++----------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index 3d23c18..a56398d 100644
--- a/drivers/gpu/drm/radeon/kv_dpm.c
+++ b/drivers/gpu/drm/radeon/kv_dpm.c
@@ -1338,13 +1338,11 @@ static int kv_enable_uvd_dpm(struct radeon_device *rdev, bool enable)
 					PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable);
 }
 
-#if 0
 static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable)
 {
 	return kv_notify_message_to_smu(rdev, enable ?
 					PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable);
 }
-#endif
 
 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)
 	return kv_enable_uvd_dpm(rdev, !gate);
 }
 
-#if 0
 static u8 kv_get_vce_boot_level(struct radeon_device *rdev)
 {
 	u8 i;
@@ -1414,6 +1411,8 @@ static int kv_update_vce_dpm(struct radeon_device *rdev,
 	int ret;
 
 	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)
 			pi->vce_boot_level = table->count - 1;
 		else
@@ -1436,11 +1435,12 @@ static int kv_update_vce_dpm(struct radeon_device *rdev,
 		kv_enable_vce_dpm(rdev, true);
 	} else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) {
 		kv_enable_vce_dpm(rdev, false);
+		/* XXX cik_vce_suspend(); */
+		kv_dpm_powergate_vce(rdev, true);
 	}
 
 	return 0;
 }
-#endif
 
 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)
 {
 	struct kv_power_info *pi = kv_get_pi(rdev);
 	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;
 
 	if (pi->bapm_enable) {
@@ -1798,13 +1798,12 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
 			kv_set_enabled_levels(rdev);
 			kv_force_lowest_valid(rdev);
 			kv_unforce_levels(rdev);
-#if 0
+
 			ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
 			if (ret) {
 				DRM_ERROR("kv_update_vce_dpm failed\n");
 				return ret;
 			}
-#endif
 			kv_update_sclk_t(rdev);
 		}
 	} else {
@@ -1823,13 +1822,11 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
 			kv_program_nbps_index_settings(rdev, new_ps);
 			kv_freeze_sclk_dpm(rdev, false);
 			kv_set_enabled_levels(rdev);
-#if 0
 			ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
 			if (ret) {
 				DRM_ERROR("kv_update_vce_dpm failed\n");
 				return ret;
 			}
-#endif
 			kv_update_acp_boot_level(rdev);
 			kv_update_sclk_t(rdev);
 			kv_enable_nb_dpm(rdev);
@@ -2037,6 +2034,14 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
 	struct radeon_clock_and_voltage_limits *max_limits =
 		&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;
 	sclk = min_sclk;
 
@@ -2056,6 +2061,11 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
 		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;
 
 	for (i = 0; i < ps->num_levels; i++) {
@@ -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) ==
 	    ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)
@@ -2574,6 +2585,19 @@ static int kv_parse_power_table(struct radeon_device *rdev)
 		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
 	}
 	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;
 }
 
@@ -2624,7 +2648,7 @@ int kv_dpm_init(struct radeon_device *rdev)
 	pi->caps_fps = false; /* true? */
 	pi->caps_uvd_pg = 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_acp_pg = false;
 	pi->caps_stable_p_state = false;
-- 
1.8.3.2



More information about the dri-devel mailing list