From: Alex Deucher Date: Mon, 3 May 2010 05:13:14 +0000 (-0400) Subject: drm/radeon/kms/pm: add support for no display power states X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=d7311171c4cc8d6231427f7ac5056b939a184b80;p=linux-beck.git 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 Signed-off-by: Dave Airlie --- diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 4151ad8affed..03dd6c41dc19 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -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 diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 14b7541df38a..4161a35dd3d3 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -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) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 75c825cb8790..08a328c4165a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -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) { diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e39e2b4ec979..480a83ff54d5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -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; diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index c29ac74a1d20..9149e4a3af0f 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -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 = diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index c22344b7fc58..93f18bbf744a 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -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 */ diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 7701d42c4804..e1e5255396ac 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -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, diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 1ee7fc9918ac..0dfa508fe5f2 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -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);