#define RADEON_IDLE_LOOP_MS 100
#define RADEON_RECLOCK_DELAY_MS 200
#define RADEON_WAIT_VBLANK_TIMEOUT 200
+#define RADEON_WAIT_IDLE_TIMEOUT 200
-static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
-static void radeon_pm_set_clocks_locked(struct radeon_device *rdev);
-static void radeon_pm_set_clocks(struct radeon_device *rdev);
static void radeon_pm_idle_work_handler(struct work_struct *work);
static int radeon_debugfs_pm_init(struct radeon_device *rdev);
+static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
+{
+ int i;
+
+ mutex_lock(&rdev->cp.mutex);
+
+ /* wait for GPU idle */
+ rdev->pm.gui_idle = false;
+ rdev->irq.gui_idle = true;
+ radeon_irq_set(rdev);
+ wait_event_interruptible_timeout(
+ rdev->irq.idle_queue, rdev->pm.gui_idle,
+ msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT));
+ rdev->irq.gui_idle = false;
+ radeon_irq_set(rdev);
+
+ if (!static_switch) {
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (rdev->pm.active_crtcs & (1 << i)) {
+ rdev->pm.req_vblank |= (1 << i);
+ drm_vblank_get(rdev->ddev, i);
+ }
+ }
+ }
+
+ radeon_set_power_state(rdev, static_switch);
+
+ if (!static_switch) {
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (rdev->pm.req_vblank & (1 << i)) {
+ rdev->pm.req_vblank &= ~(1 << i);
+ drm_vblank_put(rdev->ddev, i);
+ }
+ }
+ }
+
+ /* update display watermarks based on new power state */
+ radeon_update_bandwidth_info(rdev);
+ if (rdev->pm.active_crtc_count)
+ radeon_bandwidth_update(rdev);
+
+ rdev->pm.planned_action = PM_ACTION_NONE;
+
+ mutex_unlock(&rdev->cp.mutex);
+}
+
+static ssize_t radeon_get_power_state_static(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+ struct radeon_device *rdev = ddev->dev_private;
+
+ return snprintf(buf, PAGE_SIZE, "%d.%d\n", rdev->pm.current_power_state_index,
+ rdev->pm.current_clock_mode_index);
+}
+
+static ssize_t radeon_set_power_state_static(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+ struct radeon_device *rdev = ddev->dev_private;
+ int ps, cm;
+
+ if (sscanf(buf, "%u.%u", &ps, &cm) != 2) {
+ DRM_ERROR("Invalid power state!\n");
+ return count;
+ }
+
+ 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)) {
+ DRM_ERROR("Invalid power state for multi-head: %d.%d\n", ps, cm);
+ } else {
+ /* disable dynpm */
+ rdev->pm.state = PM_STATE_DISABLED;
+ rdev->pm.planned_action = PM_ACTION_NONE;
+ rdev->pm.requested_power_state_index = ps;
+ rdev->pm.requested_clock_mode_index = cm;
+ radeon_pm_set_clocks(rdev, true);
+ }
+ } else
+ DRM_ERROR("Invalid power state: %d.%d\n\n", ps, cm);
+ mutex_unlock(&rdev->pm.mutex);
+
+ return count;
+}
+
+static ssize_t radeon_get_dynpm(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+ struct radeon_device *rdev = ddev->dev_private;
+
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ (rdev->pm.state == PM_STATE_DISABLED) ? "disabled" : "enabled");
+}
+
+static ssize_t radeon_set_dynpm(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+ struct radeon_device *rdev = ddev->dev_private;
+ int tmp = simple_strtoul(buf, NULL, 10);
+
+ if (tmp == 0) {
+ /* update power mode info */
+ radeon_pm_compute_clocks(rdev);
+ /* disable dynpm */
+ mutex_lock(&rdev->pm.mutex);
+ rdev->pm.state = PM_STATE_DISABLED;
+ rdev->pm.planned_action = PM_ACTION_NONE;
+ mutex_unlock(&rdev->pm.mutex);
+ DRM_INFO("radeon: dynamic power management disabled\n");
+ } else if (tmp == 1) {
+ if (rdev->pm.num_power_states > 1) {
+ /* enable dynpm */
+ mutex_lock(&rdev->pm.mutex);
+ rdev->pm.state = PM_STATE_PAUSED;
+ rdev->pm.planned_action = PM_ACTION_DEFAULT;
+ radeon_get_power_state(rdev, rdev->pm.planned_action);
+ mutex_unlock(&rdev->pm.mutex);
+ /* update power mode info */
+ radeon_pm_compute_clocks(rdev);
+ DRM_INFO("radeon: dynamic power management enabled\n");
+ } else
+ DRM_ERROR("dynpm not valid on this system\n");
+ } else
+ DRM_ERROR("Invalid setting: %d\n", tmp);
+
+ return count;
+}
+
+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, radeon_get_power_state_static, radeon_set_power_state_static);
+static DEVICE_ATTR(dynpm, S_IRUGO | S_IWUSR, radeon_get_dynpm, radeon_set_dynpm);
+
+
static const char *pm_state_names[4] = {
"PM_STATE_DISABLED",
"PM_STATE_MINIMUM",
};
static const char *pm_state_types[5] = {
- "Default",
+ "",
"Powersave",
"Battery",
"Balanced",
DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states);
for (i = 0; i < rdev->pm.num_power_states; i++) {
- if (rdev->pm.default_power_state == &rdev->pm.power_state[i])
+ if (rdev->pm.default_power_state_index == i)
is_default = true;
else
is_default = false;
pm_state_types[rdev->pm.power_state[i].type],
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].non_clock_info.pcie_lanes);
+ 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)
+ 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++) {
if (rdev->flags & RADEON_IS_IGP)
}
}
-static struct radeon_power_state * radeon_pick_power_state(struct radeon_device *rdev,
- enum radeon_pm_state_type type)
-{
- int i, j;
- enum radeon_pm_state_type wanted_types[2];
- int wanted_count;
-
- switch (type) {
- case POWER_STATE_TYPE_DEFAULT:
- default:
- return rdev->pm.default_power_state;
- case POWER_STATE_TYPE_POWERSAVE:
- if (rdev->flags & RADEON_IS_MOBILITY) {
- wanted_types[0] = POWER_STATE_TYPE_POWERSAVE;
- wanted_types[1] = POWER_STATE_TYPE_BATTERY;
- wanted_count = 2;
- } else {
- wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE;
- wanted_count = 1;
- }
- break;
- case POWER_STATE_TYPE_BATTERY:
- if (rdev->flags & RADEON_IS_MOBILITY) {
- wanted_types[0] = POWER_STATE_TYPE_BATTERY;
- wanted_types[1] = POWER_STATE_TYPE_POWERSAVE;
- wanted_count = 2;
- } else {
- wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE;
- wanted_count = 1;
- }
- break;
- case POWER_STATE_TYPE_BALANCED:
- case POWER_STATE_TYPE_PERFORMANCE:
- wanted_types[0] = type;
- wanted_count = 1;
- break;
- }
-
- for (i = 0; i < wanted_count; i++) {
- for (j = 0; j < rdev->pm.num_power_states; j++) {
- if (rdev->pm.power_state[j].type == wanted_types[i])
- return &rdev->pm.power_state[j];
- }
- }
-
- return rdev->pm.default_power_state;
-}
-
-static struct radeon_pm_clock_info * radeon_pick_clock_mode(struct radeon_device *rdev,
- struct radeon_power_state *power_state,
- enum radeon_pm_clock_mode_type type)
-{
- switch (type) {
- case POWER_MODE_TYPE_DEFAULT:
- default:
- return power_state->default_clock_mode;
- case POWER_MODE_TYPE_LOW:
- return &power_state->clock_info[0];
- case POWER_MODE_TYPE_MID:
- if (power_state->num_clock_modes > 2)
- return &power_state->clock_info[1];
- else
- return &power_state->clock_info[0];
- break;
- case POWER_MODE_TYPE_HIGH:
- return &power_state->clock_info[power_state->num_clock_modes - 1];
- }
-
-}
-
-static void radeon_get_power_state(struct radeon_device *rdev,
- enum radeon_pm_action action)
-{
- switch (action) {
- case PM_ACTION_MINIMUM:
- rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_BATTERY);
- rdev->pm.requested_clock_mode =
- radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_LOW);
- break;
- case PM_ACTION_DOWNCLOCK:
- rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_POWERSAVE);
- rdev->pm.requested_clock_mode =
- radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_MID);
- break;
- case PM_ACTION_UPCLOCK:
- rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_DEFAULT);
- rdev->pm.requested_clock_mode =
- radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_HIGH);
- break;
- case PM_ACTION_NONE:
- default:
- DRM_ERROR("Requested mode for not defined action\n");
- return;
- }
- DRM_INFO("Requested: e: %d m: %d p: %d\n",
- rdev->pm.requested_clock_mode->sclk,
- rdev->pm.requested_clock_mode->mclk,
- rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
-}
-
-static inline void radeon_sync_with_vblank(struct radeon_device *rdev)
+void radeon_sync_with_vblank(struct radeon_device *rdev)
{
if (rdev->pm.active_crtcs) {
rdev->pm.vblank_sync = false;
}
}
-static void radeon_set_power_state(struct radeon_device *rdev)
-{
- /* if *_clock_mode are the same, *_power_state are as well */
- if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode)
- return;
-
- DRM_INFO("Setting: e: %d m: %d p: %d\n",
- rdev->pm.requested_clock_mode->sclk,
- rdev->pm.requested_clock_mode->mclk,
- rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
-
- /* set pcie lanes */
- /* TODO */
-
- /* set voltage */
- /* TODO */
-
- /* set engine clock */
- radeon_sync_with_vblank(rdev);
- radeon_pm_debug_check_in_vbl(rdev, false);
- radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk);
- radeon_pm_debug_check_in_vbl(rdev, true);
-
-#if 0
- /* set memory clock */
- if (rdev->asic->set_memory_clock) {
- radeon_sync_with_vblank(rdev);
- radeon_pm_debug_check_in_vbl(rdev, false);
- radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk);
- radeon_pm_debug_check_in_vbl(rdev, true);
- }
-#endif
-
- rdev->pm.current_power_state = rdev->pm.requested_power_state;
- rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode;
-}
-
int radeon_pm_init(struct radeon_device *rdev)
{
rdev->pm.state = PM_STATE_DISABLED;
rdev->pm.planned_action = PM_ACTION_NONE;
- rdev->pm.downclocked = false;
+ rdev->pm.can_upclock = true;
+ rdev->pm.can_downclock = true;
if (rdev->bios) {
if (rdev->is_atom_bios)
DRM_ERROR("Failed to register debugfs file for PM!\n");
}
+ /* where's the best place to put this? */
+ device_create_file(rdev->dev, &dev_attr_power_state);
+ device_create_file(rdev->dev, &dev_attr_dynpm);
+
INIT_DELAYED_WORK(&rdev->pm.idle_work, radeon_pm_idle_work_handler);
- if (radeon_dynpm != -1 && radeon_dynpm) {
+ if ((radeon_dynpm != -1 && radeon_dynpm) && (rdev->pm.num_power_states > 1)) {
rdev->pm.state = PM_STATE_PAUSED;
DRM_INFO("radeon: dynamic power management enabled\n");
}
void radeon_pm_fini(struct radeon_device *rdev)
{
+ if (rdev->pm.state != PM_STATE_DISABLED) {
+ /* cancel work */
+ cancel_delayed_work_sync(&rdev->pm.idle_work);
+ /* reset default clocks */
+ rdev->pm.state = PM_STATE_DISABLED;
+ rdev->pm.planned_action = PM_ACTION_DEFAULT;
+ radeon_pm_set_clocks(rdev, false);
+ } else if ((rdev->pm.current_power_state_index !=
+ rdev->pm.default_power_state_index) ||
+ (rdev->pm.current_clock_mode_index != 0)) {
+ rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index;
+ rdev->pm.requested_clock_mode_index = 0;
+ mutex_lock(&rdev->pm.mutex);
+ radeon_pm_set_clocks(rdev, true);
+ mutex_unlock(&rdev->pm.mutex);
+ }
+
+ device_remove_file(rdev->dev, &dev_attr_power_state);
+ device_remove_file(rdev->dev, &dev_attr_dynpm);
+
if (rdev->pm.i2c_bus)
radeon_i2c_destroy(rdev->pm.i2c_bus);
}
void radeon_pm_compute_clocks(struct radeon_device *rdev)
{
struct drm_device *ddev = rdev->ddev;
- struct drm_connector *connector;
+ struct drm_crtc *crtc;
struct radeon_crtc *radeon_crtc;
- int count = 0;
if (rdev->pm.state == PM_STATE_DISABLED)
return;
mutex_lock(&rdev->pm.mutex);
rdev->pm.active_crtcs = 0;
- list_for_each_entry(connector,
- &ddev->mode_config.connector_list, head) {
- if (connector->encoder &&
- connector->dpms != DRM_MODE_DPMS_OFF) {
- radeon_crtc = to_radeon_crtc(connector->encoder->crtc);
+ rdev->pm.active_crtc_count = 0;
+ list_for_each_entry(crtc,
+ &ddev->mode_config.crtc_list, head) {
+ radeon_crtc = to_radeon_crtc(crtc);
+ if (radeon_crtc->enabled) {
rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
- ++count;
+ rdev->pm.active_crtc_count++;
}
}
- if (count > 1) {
+ 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;
- if (rdev->pm.downclocked)
- radeon_pm_set_clocks(rdev);
+ radeon_pm_set_clocks(rdev, false);
DRM_DEBUG("radeon: dynamic power management deactivated\n");
}
- } else if (count == 1) {
+ } else if (rdev->pm.active_crtc_count == 1) {
/* TODO: Increase clocks if needed for current mode */
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);
+ radeon_pm_set_clocks(rdev, false);
queue_delayed_work(rdev->wq, &rdev->pm.idle_work,
msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
- }
- else if (rdev->pm.state == PM_STATE_PAUSED) {
+ } else if (rdev->pm.state == PM_STATE_PAUSED) {
rdev->pm.state = PM_STATE_ACTIVE;
queue_delayed_work(rdev->wq, &rdev->pm.idle_work,
msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
DRM_DEBUG("radeon: dynamic power management activated\n");
}
- }
- else { /* count == 0 */
+ } else { /* count == 0 */
if (rdev->pm.state != PM_STATE_MINIMUM) {
cancel_delayed_work(&rdev->pm.idle_work);
rdev->pm.state = PM_STATE_MINIMUM;
rdev->pm.planned_action = PM_ACTION_MINIMUM;
- radeon_pm_set_clocks(rdev);
+ radeon_pm_set_clocks(rdev, false);
}
}
mutex_unlock(&rdev->pm.mutex);
}
-static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish)
+bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish)
{
- u32 stat_crtc1 = 0, stat_crtc2 = 0;
+ u32 stat_crtc = 0;
bool in_vbl = true;
- if (ASIC_IS_AVIVO(rdev)) {
+ if (ASIC_IS_DCE4(rdev)) {
if (rdev->pm.active_crtcs & (1 << 0)) {
- stat_crtc1 = RREG32(D1CRTC_STATUS);
- if (!(stat_crtc1 & 1))
+ stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
+ if (!(stat_crtc & 1))
in_vbl = false;
}
if (rdev->pm.active_crtcs & (1 << 1)) {
- stat_crtc2 = RREG32(D2CRTC_STATUS);
- if (!(stat_crtc2 & 1))
+ stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
+ if (!(stat_crtc & 1))
+ in_vbl = false;
+ }
+ if (rdev->pm.active_crtcs & (1 << 2)) {
+ stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
+ if (!(stat_crtc & 1))
+ in_vbl = false;
+ }
+ if (rdev->pm.active_crtcs & (1 << 3)) {
+ stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
+ if (!(stat_crtc & 1))
+ in_vbl = false;
+ }
+ if (rdev->pm.active_crtcs & (1 << 4)) {
+ stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
+ if (!(stat_crtc & 1))
+ in_vbl = false;
+ }
+ if (rdev->pm.active_crtcs & (1 << 5)) {
+ stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+ if (!(stat_crtc & 1))
+ in_vbl = false;
+ }
+ } else if (ASIC_IS_AVIVO(rdev)) {
+ if (rdev->pm.active_crtcs & (1 << 0)) {
+ stat_crtc = RREG32(D1CRTC_STATUS);
+ if (!(stat_crtc & 1))
+ in_vbl = false;
+ }
+ if (rdev->pm.active_crtcs & (1 << 1)) {
+ stat_crtc = RREG32(D2CRTC_STATUS);
+ if (!(stat_crtc & 1))
+ in_vbl = false;
+ }
+ } else {
+ if (rdev->pm.active_crtcs & (1 << 0)) {
+ stat_crtc = RREG32(RADEON_CRTC_STATUS);
+ if (!(stat_crtc & 1))
+ in_vbl = false;
+ }
+ if (rdev->pm.active_crtcs & (1 << 1)) {
+ stat_crtc = RREG32(RADEON_CRTC2_STATUS);
+ if (!(stat_crtc & 1))
in_vbl = false;
}
}
if (in_vbl == false)
- DRM_INFO("not in vbl for pm change %08x %08x at %s\n", stat_crtc1,
- stat_crtc2, finish ? "exit" : "entry");
+ DRM_INFO("not in vbl for pm change %08x at %s\n", stat_crtc,
+ finish ? "exit" : "entry");
return in_vbl;
}
-static void radeon_pm_set_clocks_locked(struct radeon_device *rdev)
-{
- /*radeon_fence_wait_last(rdev);*/
- switch (rdev->pm.planned_action) {
- case PM_ACTION_UPCLOCK:
- rdev->pm.downclocked = false;
- break;
- case PM_ACTION_DOWNCLOCK:
- rdev->pm.downclocked = true;
- break;
- case PM_ACTION_MINIMUM:
- break;
- case PM_ACTION_NONE:
- DRM_ERROR("%s: PM_ACTION_NONE\n", __func__);
- break;
- }
-
- radeon_set_power_state(rdev);
- rdev->pm.planned_action = PM_ACTION_NONE;
-}
-
-static void radeon_pm_set_clocks(struct radeon_device *rdev)
-{
- radeon_get_power_state(rdev, rdev->pm.planned_action);
- mutex_lock(&rdev->cp.mutex);
-
- if (rdev->pm.active_crtcs & (1 << 0)) {
- rdev->pm.req_vblank |= (1 << 0);
- drm_vblank_get(rdev->ddev, 0);
- }
- if (rdev->pm.active_crtcs & (1 << 1)) {
- rdev->pm.req_vblank |= (1 << 1);
- drm_vblank_get(rdev->ddev, 1);
- }
- radeon_pm_set_clocks_locked(rdev);
- if (rdev->pm.req_vblank & (1 << 0)) {
- rdev->pm.req_vblank &= ~(1 << 0);
- drm_vblank_put(rdev->ddev, 0);
- }
- if (rdev->pm.req_vblank & (1 << 1)) {
- rdev->pm.req_vblank &= ~(1 << 1);
- drm_vblank_put(rdev->ddev, 1);
- }
-
- mutex_unlock(&rdev->cp.mutex);
-}
static void radeon_pm_idle_work_handler(struct work_struct *work)
{
if (rdev->pm.planned_action == PM_ACTION_DOWNCLOCK) {
rdev->pm.planned_action = PM_ACTION_NONE;
} else if (rdev->pm.planned_action == PM_ACTION_NONE &&
- rdev->pm.downclocked) {
+ rdev->pm.can_upclock) {
rdev->pm.planned_action =
PM_ACTION_UPCLOCK;
rdev->pm.action_timeout = jiffies +
if (rdev->pm.planned_action == PM_ACTION_UPCLOCK) {
rdev->pm.planned_action = PM_ACTION_NONE;
} else if (rdev->pm.planned_action == PM_ACTION_NONE &&
- !rdev->pm.downclocked) {
+ rdev->pm.can_downclock) {
rdev->pm.planned_action =
PM_ACTION_DOWNCLOCK;
rdev->pm.action_timeout = jiffies +
if (rdev->pm.planned_action != PM_ACTION_NONE &&
jiffies > rdev->pm.action_timeout) {
- radeon_pm_set_clocks(rdev);
+ radeon_pm_set_clocks(rdev, false);
}
}
mutex_unlock(&rdev->pm.mutex);