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

Commit 27810fb2 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon/pm: fix multi-head profile handling on BTC+ (v2)

Starting on BTC, there are no longer separate states for
single head and multi-head, we just use the high mclk/voltage
for all states for multi-head.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=49981



v2: fix typo

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent eb2c27a0
Loading
Loading
Loading
Loading
+58 −0
Original line number Original line Diff line number Diff line
@@ -325,6 +325,64 @@ void sumo_pm_init_profile(struct radeon_device *rdev)
		rdev->pm.power_state[idx].num_clock_modes - 1;
		rdev->pm.power_state[idx].num_clock_modes - 1;
}
}


/**
 * btc_pm_init_profile - Initialize power profiles callback.
 *
 * @rdev: radeon_device pointer
 *
 * Initialize the power states used in profile mode
 * (BTC, cayman).
 * Used for profile mode only.
 */
void btc_pm_init_profile(struct radeon_device *rdev)
{
	int idx;

	/* default */
	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
	/* starting with BTC, there is one state that is used for both
	 * MH and SH.  Difference is that we always use the high clock index for
	 * mclk.
	 */
	if (rdev->flags & RADEON_IS_MOBILITY)
		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
	else
		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
	/* low sh */
	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
	/* mid sh */
	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
	/* high sh */
	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
	/* low mh */
	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
	/* mid mh */
	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
	/* high mh */
	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
}

/**
/**
 * evergreen_pm_misc - set additional pm hw parameters callback.
 * evergreen_pm_misc - set additional pm hw parameters callback.
 *
 *
+2 −2
Original line number Original line Diff line number Diff line
@@ -1357,7 +1357,7 @@ static struct radeon_asic btc_asic = {
		.misc = &evergreen_pm_misc,
		.misc = &evergreen_pm_misc,
		.prepare = &evergreen_pm_prepare,
		.prepare = &evergreen_pm_prepare,
		.finish = &evergreen_pm_finish,
		.finish = &evergreen_pm_finish,
		.init_profile = &r600_pm_init_profile,
		.init_profile = &btc_pm_init_profile,
		.get_dynpm_state = &r600_pm_get_dynpm_state,
		.get_dynpm_state = &r600_pm_get_dynpm_state,
		.get_engine_clock = &radeon_atom_get_engine_clock,
		.get_engine_clock = &radeon_atom_get_engine_clock,
		.set_engine_clock = &radeon_atom_set_engine_clock,
		.set_engine_clock = &radeon_atom_set_engine_clock,
@@ -1462,7 +1462,7 @@ static struct radeon_asic cayman_asic = {
		.misc = &evergreen_pm_misc,
		.misc = &evergreen_pm_misc,
		.prepare = &evergreen_pm_prepare,
		.prepare = &evergreen_pm_prepare,
		.finish = &evergreen_pm_finish,
		.finish = &evergreen_pm_finish,
		.init_profile = &r600_pm_init_profile,
		.init_profile = &btc_pm_init_profile,
		.get_dynpm_state = &r600_pm_get_dynpm_state,
		.get_dynpm_state = &r600_pm_get_dynpm_state,
		.get_engine_clock = &radeon_atom_get_engine_clock,
		.get_engine_clock = &radeon_atom_get_engine_clock,
		.set_engine_clock = &radeon_atom_set_engine_clock,
		.set_engine_clock = &radeon_atom_set_engine_clock,
+1 −0
Original line number Original line Diff line number Diff line
@@ -420,6 +420,7 @@ extern void evergreen_pm_misc(struct radeon_device *rdev);
extern void evergreen_pm_prepare(struct radeon_device *rdev);
extern void evergreen_pm_prepare(struct radeon_device *rdev);
extern void evergreen_pm_finish(struct radeon_device *rdev);
extern void evergreen_pm_finish(struct radeon_device *rdev);
extern void sumo_pm_init_profile(struct radeon_device *rdev);
extern void sumo_pm_init_profile(struct radeon_device *rdev);
extern void btc_pm_init_profile(struct radeon_device *rdev);
extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
+15 −2
Original line number Original line Diff line number Diff line
@@ -167,8 +167,21 @@ static void radeon_set_power_state(struct radeon_device *rdev)
		if (sclk > rdev->pm.default_sclk)
		if (sclk > rdev->pm.default_sclk)
			sclk = rdev->pm.default_sclk;
			sclk = rdev->pm.default_sclk;


		/* starting with BTC, there is one state that is used for both
		 * MH and SH.  Difference is that we always use the high clock index for
		 * mclk.
		 */
		if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
		    (rdev->family >= CHIP_BARTS) &&
		    rdev->pm.active_crtc_count &&
		    ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) ||
		     (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX)))
			mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
				clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].mclk;
		else
			mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
			mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
				clock_info[rdev->pm.requested_clock_mode_index].mclk;
				clock_info[rdev->pm.requested_clock_mode_index].mclk;

		if (mclk > rdev->pm.default_mclk)
		if (mclk > rdev->pm.default_mclk)
			mclk = rdev->pm.default_mclk;
			mclk = rdev->pm.default_mclk;