Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 797f203f authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon/dpm: adjust power state properly for UVD on SI



There are some hardware issue with reclocking on SI when
UVD is active, so use a stable power state when UVD is
active.  Fixes possible hangs and performance issues when
using UVD on SI.

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b841ce7b
Loading
Loading
Loading
Loading
+32 −12
Original line number Original line Diff line number Diff line
@@ -2903,7 +2903,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
{
{
	struct ni_ps *ps = ni_get_ps(rps);
	struct ni_ps *ps = ni_get_ps(rps);
	struct radeon_clock_and_voltage_limits *max_limits;
	struct radeon_clock_and_voltage_limits *max_limits;
	bool disable_mclk_switching;
	bool disable_mclk_switching = false;
	bool disable_sclk_switching = false;
	u32 mclk, sclk;
	u32 mclk, sclk;
	u16 vddc, vddci;
	u16 vddc, vddci;
	int i;
	int i;
@@ -2911,8 +2912,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
	if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
	if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
	    ni_dpm_vblank_too_short(rdev))
	    ni_dpm_vblank_too_short(rdev))
		disable_mclk_switching = true;
		disable_mclk_switching = true;
	else

		disable_mclk_switching = false;
	if (rps->vclk || rps->dclk) {
		disable_mclk_switching = true;
		disable_sclk_switching = true;
	}


	if (rdev->pm.dpm.ac_power)
	if (rdev->pm.dpm.ac_power)
		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
@@ -2940,28 +2944,44 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,


	if (disable_mclk_switching) {
	if (disable_mclk_switching) {
		mclk  = ps->performance_levels[ps->performance_level_count - 1].mclk;
		mclk  = ps->performance_levels[ps->performance_level_count - 1].mclk;
		sclk = ps->performance_levels[0].sclk;
		vddc = ps->performance_levels[0].vddc;
		vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
		vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
	} else {
	} else {
		sclk = ps->performance_levels[0].sclk;
		mclk = ps->performance_levels[0].mclk;
		mclk = ps->performance_levels[0].mclk;
		vddc = ps->performance_levels[0].vddc;
		vddci = ps->performance_levels[0].vddci;
		vddci = ps->performance_levels[0].vddci;
	}
	}


	if (disable_sclk_switching) {
		sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;
		vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;
	} else {
		sclk = ps->performance_levels[0].sclk;
		vddc = ps->performance_levels[0].vddc;
	}

	/* adjusted low state */
	/* adjusted low state */
	ps->performance_levels[0].sclk = sclk;
	ps->performance_levels[0].sclk = sclk;
	ps->performance_levels[0].mclk = mclk;
	ps->performance_levels[0].mclk = mclk;
	ps->performance_levels[0].vddc = vddc;
	ps->performance_levels[0].vddc = vddc;
	ps->performance_levels[0].vddci = vddci;
	ps->performance_levels[0].vddci = vddci;


	if (disable_sclk_switching) {
		sclk = ps->performance_levels[0].sclk;
		for (i = 1; i < ps->performance_level_count; i++) {
			if (sclk < ps->performance_levels[i].sclk)
				sclk = ps->performance_levels[i].sclk;
		}
		for (i = 0; i < ps->performance_level_count; i++) {
			ps->performance_levels[i].sclk = sclk;
			ps->performance_levels[i].vddc = vddc;
		}
	} else {
		for (i = 1; i < ps->performance_level_count; i++) {
		for (i = 1; i < ps->performance_level_count; i++) {
			if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
			if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
				ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
				ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
			if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
			if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
				ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
				ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
		}
		}
	}


	if (disable_mclk_switching) {
	if (disable_mclk_switching) {
		mclk = ps->performance_levels[0].mclk;
		mclk = ps->performance_levels[0].mclk;