diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 118 |
1 files changed, 57 insertions, 61 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 4f6b7fc7ad3..984097b907e 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -508,17 +508,21 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev, } else if (strncmp("auto", buf, strlen("auto")) == 0) { level = RADEON_DPM_FORCED_LEVEL_AUTO; } else { - mutex_unlock(&rdev->pm.mutex); count = -EINVAL; goto fail; } if (rdev->asic->dpm.force_performance_level) { + if (rdev->pm.dpm.thermal_active) { + count = -EINVAL; + goto fail; + } ret = radeon_dpm_force_performance_level(rdev, level); if (ret) count = -EINVAL; } - mutex_unlock(&rdev->pm.mutex); fail: + mutex_unlock(&rdev->pm.mutex); + return count; } @@ -533,8 +537,7 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, struct device_attribute *attr, char *buf) { - struct drm_device *ddev = dev_get_drvdata(dev); - struct radeon_device *rdev = ddev->dev_private; + struct radeon_device *rdev = dev_get_drvdata(dev); int temp; if (rdev->asic->pm.get_temperature) @@ -549,8 +552,7 @@ static ssize_t radeon_hwmon_show_temp_thresh(struct device *dev, struct device_attribute *attr, char *buf) { - struct drm_device *ddev = dev_get_drvdata(dev); - struct radeon_device *rdev = ddev->dev_private; + struct radeon_device *rdev = dev_get_drvdata(dev); int hyst = to_sensor_dev_attr(attr)->index; int temp; @@ -562,23 +564,14 @@ static ssize_t radeon_hwmon_show_temp_thresh(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", temp); } -static ssize_t radeon_hwmon_show_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "radeon\n"); -} - static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 1); -static SENSOR_DEVICE_ATTR(name, S_IRUGO, radeon_hwmon_show_name, NULL, 0); static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, - &sensor_dev_attr_name.dev_attr.attr, NULL }; @@ -586,8 +579,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, struct attribute *attr, int index) { struct device *dev = container_of(kobj, struct device, kobj); - struct drm_device *ddev = dev_get_drvdata(dev); - struct radeon_device *rdev = ddev->dev_private; + struct radeon_device *rdev = dev_get_drvdata(dev); /* Skip limit attributes if DPM is not enabled */ if (rdev->pm.pm_method != PM_METHOD_DPM && @@ -603,11 +595,15 @@ static const struct attribute_group hwmon_attrgroup = { .is_visible = hwmon_attributes_visible, }; +static const struct attribute_group *hwmon_groups[] = { + &hwmon_attrgroup, + NULL +}; + static int radeon_hwmon_init(struct radeon_device *rdev) { int err = 0; - - rdev->pm.int_hwmon_dev = NULL; + struct device *hwmon_dev; switch (rdev->pm.int_thermal_type) { case THERMAL_TYPE_RV6XX: @@ -620,20 +616,13 @@ static int radeon_hwmon_init(struct radeon_device *rdev) case THERMAL_TYPE_KV: if (rdev->asic->pm.get_temperature == NULL) return err; - rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); - if (IS_ERR(rdev->pm.int_hwmon_dev)) { - err = PTR_ERR(rdev->pm.int_hwmon_dev); + hwmon_dev = hwmon_device_register_with_groups(rdev->dev, + "radeon", rdev, + hwmon_groups); + if (IS_ERR(hwmon_dev)) { + err = PTR_ERR(hwmon_dev); dev_err(rdev->dev, "Unable to register hwmon device: %d\n", err); - break; - } - dev_set_drvdata(rdev->pm.int_hwmon_dev, rdev->ddev); - err = sysfs_create_group(&rdev->pm.int_hwmon_dev->kobj, - &hwmon_attrgroup); - if (err) { - dev_err(rdev->dev, - "Unable to create hwmon sysfs file: %d\n", err); - hwmon_device_unregister(rdev->dev); } break; default: @@ -643,14 +632,6 @@ static int radeon_hwmon_init(struct radeon_device *rdev) return err; } -static void radeon_hwmon_fini(struct radeon_device *rdev) -{ - if (rdev->pm.int_hwmon_dev) { - sysfs_remove_group(&rdev->pm.int_hwmon_dev->kobj, &hwmon_attrgroup); - hwmon_device_unregister(rdev->pm.int_hwmon_dev); - } -} - static void radeon_dpm_thermal_work_handler(struct work_struct *work) { struct radeon_device *rdev = @@ -881,11 +862,12 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) } } - printk("switching from power state:\n"); - radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps); - printk("switching to power state:\n"); - radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps); - + if (radeon_dpm == 1) { + printk("switching from power state:\n"); + radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps); + printk("switching to power state:\n"); + radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps); + } mutex_lock(&rdev->ddev->struct_mutex); down_write(&rdev->pm.mclk_lock); mutex_lock(&rdev->ring_lock); @@ -918,12 +900,16 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) radeon_dpm_post_set_power_state(rdev); if (rdev->asic->dpm.force_performance_level) { - if (rdev->pm.dpm.thermal_active) + if (rdev->pm.dpm.thermal_active) { + enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; /* force low perf level for thermal */ radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_LOW); - else - /* otherwise, enable auto */ - radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO); + /* save the user's level */ + rdev->pm.dpm.forced_level = level; + } else { + /* otherwise, user selected level */ + radeon_dpm_force_performance_level(rdev, rdev->pm.dpm.forced_level); + } } done: @@ -1179,7 +1165,8 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) mutex_lock(&rdev->pm.mutex); radeon_dpm_init(rdev); rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps; - radeon_dpm_print_power_states(rdev); + if (radeon_dpm == 1) + radeon_dpm_print_power_states(rdev); radeon_dpm_setup_asic(rdev); ret = radeon_dpm_enable(rdev); mutex_unlock(&rdev->pm.mutex); @@ -1241,6 +1228,23 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_RV670: case CHIP_RS780: case CHIP_RS880: + case CHIP_CAYMAN: + case CHIP_BONAIRE: + case CHIP_KABINI: + case CHIP_KAVERI: + case CHIP_HAWAII: + /* DPM requires the RLC, RV770+ dGPU requires SMC */ + if (!rdev->rlc_fw) + rdev->pm.pm_method = PM_METHOD_PROFILE; + else if ((rdev->family >= CHIP_RV770) && + (!(rdev->flags & RADEON_IS_IGP)) && + (!rdev->smc_fw)) + rdev->pm.pm_method = PM_METHOD_PROFILE; + else if (radeon_dpm == 1) + rdev->pm.pm_method = PM_METHOD_DPM; + else + rdev->pm.pm_method = PM_METHOD_PROFILE; + break; case CHIP_RV770: case CHIP_RV730: case CHIP_RV710: @@ -1256,16 +1260,12 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_BARTS: case CHIP_TURKS: case CHIP_CAICOS: - case CHIP_CAYMAN: case CHIP_ARUBA: case CHIP_TAHITI: case CHIP_PITCAIRN: case CHIP_VERDE: case CHIP_OLAND: case CHIP_HAINAN: - case CHIP_BONAIRE: - case CHIP_KABINI: - case CHIP_KAVERI: /* DPM requires the RLC, RV770+ dGPU requires SMC */ if (!rdev->rlc_fw) rdev->pm.pm_method = PM_METHOD_PROFILE; @@ -1273,10 +1273,10 @@ int radeon_pm_init(struct radeon_device *rdev) (!(rdev->flags & RADEON_IS_IGP)) && (!rdev->smc_fw)) rdev->pm.pm_method = PM_METHOD_PROFILE; - else if (radeon_dpm == 1) - rdev->pm.pm_method = PM_METHOD_DPM; - else + else if (radeon_dpm == 0) rdev->pm.pm_method = PM_METHOD_PROFILE; + else + rdev->pm.pm_method = PM_METHOD_DPM; break; default: /* default to profile method */ @@ -1314,8 +1314,6 @@ static void radeon_pm_fini_old(struct radeon_device *rdev) if (rdev->pm.power_state) kfree(rdev->pm.power_state); - - radeon_hwmon_fini(rdev); } static void radeon_pm_fini_dpm(struct radeon_device *rdev) @@ -1335,8 +1333,6 @@ static void radeon_pm_fini_dpm(struct radeon_device *rdev) if (rdev->pm.power_state) kfree(rdev->pm.power_state); - - radeon_hwmon_fini(rdev); } void radeon_pm_fini(struct radeon_device *rdev) @@ -1468,7 +1464,7 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev) */ for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { if (rdev->pm.active_crtcs & (1 << crtc)) { - vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos); + vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos, NULL, NULL); if ((vbl_status & DRM_SCANOUTPOS_VALID) && !(vbl_status & DRM_SCANOUTPOS_INVBL)) in_vbl = false; |