mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 09:41:44 +00:00
drm/radeon/kms/pm: add support for no display power states
The lowest power states often cause display problems, so only enable them when all displays are off. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
ca2af92311
commit
d7311171c4
@ -245,13 +245,15 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
radeon_crtc->enabled = true;
|
||||
/* adjust pm to dpms changes BEFORE enabling crtcs */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
atombios_enable_crtc(crtc, ATOM_ENABLE);
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
|
||||
atombios_blank_crtc(crtc, ATOM_DISABLE);
|
||||
drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
|
||||
radeon_crtc_load_lut(crtc);
|
||||
radeon_crtc->enabled = true;
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
@ -262,11 +264,10 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
|
||||
atombios_enable_crtc(crtc, ATOM_DISABLE);
|
||||
radeon_crtc->enabled = false;
|
||||
/* adjust pm to dpms changes AFTER disabling crtcs */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
break;
|
||||
}
|
||||
|
||||
/* adjust pm to dpms change */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -87,7 +87,7 @@ void r100_get_power_state(struct radeon_device *rdev,
|
||||
} else {
|
||||
if (rdev->pm.active_crtc_count > 1) {
|
||||
for (i = 0; i < rdev->pm.num_power_states; i++) {
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
|
||||
continue;
|
||||
else if (i >= rdev->pm.current_power_state_index) {
|
||||
rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
|
||||
@ -101,6 +101,12 @@ void r100_get_power_state(struct radeon_device *rdev,
|
||||
rdev->pm.requested_power_state_index =
|
||||
rdev->pm.current_power_state_index - 1;
|
||||
}
|
||||
/* don't use the power state if crtcs are active and no display flag is set */
|
||||
if ((rdev->pm.active_crtc_count > 0) &&
|
||||
(rdev->pm.power_state[rdev->pm.requested_power_state_index].clock_info[0].flags &
|
||||
RADEON_PM_MODE_NO_DISPLAY)) {
|
||||
rdev->pm.requested_power_state_index++;
|
||||
}
|
||||
break;
|
||||
case PM_ACTION_UPCLOCK:
|
||||
if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) {
|
||||
@ -109,7 +115,7 @@ void r100_get_power_state(struct radeon_device *rdev,
|
||||
} else {
|
||||
if (rdev->pm.active_crtc_count > 1) {
|
||||
for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) {
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
|
||||
continue;
|
||||
else if (i <= rdev->pm.current_power_state_index) {
|
||||
rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
|
||||
@ -215,7 +221,7 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch)
|
||||
rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
|
||||
rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
|
||||
} else
|
||||
DRM_INFO("GUI not idle!!!\n");
|
||||
DRM_INFO("pm: GUI not idle!!!\n");
|
||||
}
|
||||
|
||||
void r100_pm_misc(struct radeon_device *rdev)
|
||||
|
@ -120,7 +120,7 @@ void r600_get_power_state(struct radeon_device *rdev,
|
||||
} else {
|
||||
if (rdev->pm.active_crtc_count > 1) {
|
||||
for (i = 0; i < rdev->pm.num_power_states; i++) {
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
|
||||
continue;
|
||||
else if (i >= rdev->pm.current_power_state_index) {
|
||||
rdev->pm.requested_power_state_index =
|
||||
@ -136,6 +136,13 @@ void r600_get_power_state(struct radeon_device *rdev,
|
||||
rdev->pm.current_power_state_index - 1;
|
||||
}
|
||||
rdev->pm.requested_clock_mode_index = 0;
|
||||
/* don't use the power state if crtcs are active and no display flag is set */
|
||||
if ((rdev->pm.active_crtc_count > 0) &&
|
||||
(rdev->pm.power_state[rdev->pm.requested_power_state_index].
|
||||
clock_info[rdev->pm.requested_clock_mode_index].flags &
|
||||
RADEON_PM_MODE_NO_DISPLAY)) {
|
||||
rdev->pm.requested_power_state_index++;
|
||||
}
|
||||
break;
|
||||
case PM_ACTION_UPCLOCK:
|
||||
if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) {
|
||||
@ -144,7 +151,7 @@ void r600_get_power_state(struct radeon_device *rdev,
|
||||
} else {
|
||||
if (rdev->pm.active_crtc_count > 1) {
|
||||
for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) {
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
|
||||
continue;
|
||||
else if (i <= rdev->pm.current_power_state_index) {
|
||||
rdev->pm.requested_power_state_index =
|
||||
@ -179,7 +186,7 @@ void r600_get_power_state(struct radeon_device *rdev,
|
||||
rdev->pm.requested_power_state_index = -1;
|
||||
/* start at 1 as we don't want the default mode */
|
||||
for (i = 1; i < rdev->pm.num_power_states; i++) {
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
|
||||
continue;
|
||||
else if ((rdev->pm.power_state[i].type == POWER_STATE_TYPE_PERFORMANCE) ||
|
||||
(rdev->pm.power_state[i].type == POWER_STATE_TYPE_BATTERY)) {
|
||||
@ -210,6 +217,13 @@ void r600_get_power_state(struct radeon_device *rdev,
|
||||
rdev->pm.requested_clock_mode_index = 0;
|
||||
rdev->pm.can_downclock = false;
|
||||
}
|
||||
/* don't use the power state if crtcs are active and no display flag is set */
|
||||
if ((rdev->pm.active_crtc_count > 0) &&
|
||||
(rdev->pm.power_state[rdev->pm.requested_power_state_index].
|
||||
clock_info[rdev->pm.requested_clock_mode_index].flags &
|
||||
RADEON_PM_MODE_NO_DISPLAY)) {
|
||||
rdev->pm.requested_clock_mode_index++;
|
||||
}
|
||||
break;
|
||||
case PM_ACTION_UPCLOCK:
|
||||
if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) {
|
||||
|
@ -658,6 +658,9 @@ struct radeon_voltage {
|
||||
u32 voltage;
|
||||
};
|
||||
|
||||
/* clock mode flags */
|
||||
#define RADEON_PM_MODE_NO_DISPLAY (1 << 0)
|
||||
|
||||
struct radeon_pm_clock_info {
|
||||
/* memory clock */
|
||||
u32 mclk;
|
||||
@ -665,12 +668,12 @@ struct radeon_pm_clock_info {
|
||||
u32 sclk;
|
||||
/* voltage info */
|
||||
struct radeon_voltage voltage;
|
||||
/* standardized clock flags - not sure we'll need these */
|
||||
/* standardized clock flags */
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
/* state flags */
|
||||
#define RADEON_PM_SINGLE_DISPLAY_ONLY (1 << 0)
|
||||
#define RADEON_PM_STATE_SINGLE_DISPLAY_ONLY (1 << 0)
|
||||
|
||||
struct radeon_power_state {
|
||||
enum radeon_pm_state_type type;
|
||||
|
@ -1549,7 +1549,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
|
||||
power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex;
|
||||
}
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
/* order matters! */
|
||||
if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
|
||||
@ -1568,7 +1568,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_PERFORMANCE;
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
}
|
||||
if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
@ -1577,7 +1577,10 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
} else if (state_index == 0) {
|
||||
rdev->pm.power_state[state_index].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
state_index++;
|
||||
break;
|
||||
@ -1613,7 +1616,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
|
||||
power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex;
|
||||
}
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
rdev->pm.power_state[state_index].misc2 = misc2;
|
||||
/* order matters! */
|
||||
@ -1633,14 +1636,14 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_PERFORMANCE;
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
}
|
||||
if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BALANCED;
|
||||
if (misc2 & ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT)
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
@ -1648,7 +1651,10 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
} else if (state_index == 0) {
|
||||
rdev->pm.power_state[state_index].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
state_index++;
|
||||
break;
|
||||
@ -1690,7 +1696,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex;
|
||||
}
|
||||
}
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
rdev->pm.power_state[state_index].misc2 = misc2;
|
||||
/* order matters! */
|
||||
@ -1710,7 +1716,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_PERFORMANCE;
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
}
|
||||
if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
@ -1721,6 +1727,9 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.default_power_state_index = state_index;
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
} else if (state_index == 0) {
|
||||
rdev->pm.power_state[state_index].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
state_index++;
|
||||
break;
|
||||
@ -1734,7 +1743,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index - 1].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index - 1].clock_info[0];
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].misc = 0;
|
||||
rdev->pm.power_state[state_index].misc2 = 0;
|
||||
}
|
||||
@ -1881,7 +1890,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].flags = 0;
|
||||
if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
|
||||
rdev->pm.power_state[state_index].flags |=
|
||||
RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
@ -1892,6 +1901,12 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
state_index++;
|
||||
}
|
||||
}
|
||||
/* if multiple clock modes, mark the lowest as no display */
|
||||
for (i = 0; i < state_index; i++) {
|
||||
if (rdev->pm.power_state[i].num_clock_modes > 1)
|
||||
rdev->pm.power_state[i].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
/* first mode is usually default */
|
||||
if (rdev->pm.default_power_state_index == -1) {
|
||||
rdev->pm.power_state[0].type =
|
||||
|
@ -2437,7 +2437,7 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)
|
||||
if (rev > 6)
|
||||
rdev->pm.power_state[state_index].pcie_lanes =
|
||||
RBIOS8(offset + 0x5 + 0x10);
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
state_index++;
|
||||
} else {
|
||||
/* XXX figure out some good default low power mode for mobility cards w/out power tables */
|
||||
|
@ -314,6 +314,9 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
radeon_crtc->enabled = true;
|
||||
/* adjust pm to dpms changes BEFORE enabling crtcs */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
if (radeon_crtc->crtc_id)
|
||||
WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask));
|
||||
else {
|
||||
@ -323,7 +326,6 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
}
|
||||
drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
|
||||
radeon_crtc_load_lut(crtc);
|
||||
radeon_crtc->enabled = true;
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
@ -337,11 +339,10 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask);
|
||||
}
|
||||
radeon_crtc->enabled = false;
|
||||
/* adjust pm to dpms changes AFTER disabling crtcs */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
break;
|
||||
}
|
||||
|
||||
/* adjust pm to dpms change */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
}
|
||||
|
||||
int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
|
@ -58,7 +58,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!static_switch)
|
||||
if (rdev->pm.state != PM_STATE_DISABLED)
|
||||
radeon_get_power_state(rdev, rdev->pm.planned_action);
|
||||
|
||||
mutex_lock(&rdev->ddev->struct_mutex);
|
||||
@ -147,8 +147,11 @@ static ssize_t radeon_set_power_state_static(struct device *dev,
|
||||
mutex_lock(&rdev->pm.mutex);
|
||||
if ((ps >= 0) && (ps < rdev->pm.num_power_states) &&
|
||||
(cm >= 0) && (cm < rdev->pm.power_state[ps].num_clock_modes)) {
|
||||
if ((rdev->pm.active_crtc_count > 1) &&
|
||||
(rdev->pm.power_state[ps].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)) {
|
||||
if ((rdev->pm.active_crtc_count > 0) &&
|
||||
(rdev->pm.power_state[ps].clock_info[cm].flags & RADEON_PM_MODE_NO_DISPLAY)) {
|
||||
DRM_ERROR("Invalid power state for display: %d.%d\n", ps, cm);
|
||||
} else if ((rdev->pm.active_crtc_count > 1) &&
|
||||
(rdev->pm.power_state[ps].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)) {
|
||||
DRM_ERROR("Invalid power state for multi-head: %d.%d\n", ps, cm);
|
||||
} else {
|
||||
/* disable dynpm */
|
||||
@ -248,7 +251,7 @@ static void radeon_print_power_mode_info(struct radeon_device *rdev)
|
||||
is_default ? "(default)" : "");
|
||||
if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP))
|
||||
DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].pcie_lanes);
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)
|
||||
if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
|
||||
DRM_INFO("\tSingle display only\n");
|
||||
DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes);
|
||||
for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) {
|
||||
@ -261,6 +264,8 @@ static void radeon_print_power_mode_info(struct radeon_device *rdev)
|
||||
j,
|
||||
rdev->pm.power_state[i].clock_info[j].sclk * 10,
|
||||
rdev->pm.power_state[i].clock_info[j].mclk * 10);
|
||||
if (rdev->pm.power_state[i].clock_info[j].flags & RADEON_PM_MODE_NO_DISPLAY)
|
||||
DRM_INFO("\t\tNo display only\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -318,7 +323,7 @@ void radeon_pm_fini(struct radeon_device *rdev)
|
||||
/* reset default clocks */
|
||||
rdev->pm.state = PM_STATE_DISABLED;
|
||||
rdev->pm.planned_action = PM_ACTION_DEFAULT;
|
||||
radeon_pm_set_clocks(rdev, false);
|
||||
radeon_pm_set_clocks(rdev, true);
|
||||
} else if ((rdev->pm.current_power_state_index !=
|
||||
rdev->pm.default_power_state_index) ||
|
||||
(rdev->pm.current_clock_mode_index != 0)) {
|
||||
@ -342,9 +347,6 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
|
||||
if (rdev->pm.state == PM_STATE_DISABLED)
|
||||
return;
|
||||
|
||||
mutex_lock(&rdev->pm.mutex);
|
||||
|
||||
rdev->pm.active_crtcs = 0;
|
||||
@ -358,13 +360,22 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
|
||||
}
|
||||
}
|
||||
|
||||
if (rdev->pm.state == PM_STATE_DISABLED) {
|
||||
mutex_unlock(&rdev->pm.mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Note, radeon_pm_set_clocks is called with static_switch set
|
||||
* to true since we always want to statically set the clocks,
|
||||
* not wait for vbl.
|
||||
*/
|
||||
if (rdev->pm.active_crtc_count > 1) {
|
||||
if (rdev->pm.state == PM_STATE_ACTIVE) {
|
||||
cancel_delayed_work(&rdev->pm.idle_work);
|
||||
|
||||
rdev->pm.state = PM_STATE_PAUSED;
|
||||
rdev->pm.planned_action = PM_ACTION_UPCLOCK;
|
||||
radeon_pm_set_clocks(rdev, false);
|
||||
rdev->pm.planned_action = PM_ACTION_DEFAULT;
|
||||
radeon_pm_set_clocks(rdev, true);
|
||||
|
||||
DRM_DEBUG("radeon: dynamic power management deactivated\n");
|
||||
}
|
||||
@ -374,7 +385,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
|
||||
if (rdev->pm.state == PM_STATE_MINIMUM) {
|
||||
rdev->pm.state = PM_STATE_ACTIVE;
|
||||
rdev->pm.planned_action = PM_ACTION_UPCLOCK;
|
||||
radeon_pm_set_clocks(rdev, false);
|
||||
radeon_pm_set_clocks(rdev, true);
|
||||
|
||||
queue_delayed_work(rdev->wq, &rdev->pm.idle_work,
|
||||
msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
|
||||
@ -390,7 +401,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
|
||||
|
||||
rdev->pm.state = PM_STATE_MINIMUM;
|
||||
rdev->pm.planned_action = PM_ACTION_MINIMUM;
|
||||
radeon_pm_set_clocks(rdev, false);
|
||||
radeon_pm_set_clocks(rdev, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -526,6 +537,9 @@ static void radeon_pm_idle_work_handler(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
|
||||
/* Note, radeon_pm_set_clocks is called with static_switch set
|
||||
* to false since we want to wait for vbl to avoid flicker.
|
||||
*/
|
||||
if (rdev->pm.planned_action != PM_ACTION_NONE &&
|
||||
jiffies > rdev->pm.action_timeout) {
|
||||
radeon_pm_set_clocks(rdev, false);
|
||||
|
Loading…
Reference in New Issue
Block a user