aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 115d26b762cc..ed66062ae9d0 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -27,6 +27,8 @@
27#include <linux/acpi.h> 27#include <linux/acpi.h>
28#endif 28#endif
29#include <linux/power_supply.h> 29#include <linux/power_supply.h>
30#include <linux/hwmon.h>
31#include <linux/hwmon-sysfs.h>
30 32
31#define RADEON_IDLE_LOOP_MS 100 33#define RADEON_IDLE_LOOP_MS 100
32#define RADEON_RECLOCK_DELAY_MS 200 34#define RADEON_RECLOCK_DELAY_MS 200
@@ -423,6 +425,82 @@ fail:
423static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); 425static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile);
424static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); 426static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method);
425 427
428static ssize_t radeon_hwmon_show_temp(struct device *dev,
429 struct device_attribute *attr,
430 char *buf)
431{
432 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
433 struct radeon_device *rdev = ddev->dev_private;
434 u32 temp;
435
436 switch (rdev->pm.int_thermal_type) {
437 case THERMAL_TYPE_RV6XX:
438 temp = rv6xx_get_temp(rdev);
439 break;
440 case THERMAL_TYPE_RV770:
441 temp = rv770_get_temp(rdev);
442 break;
443 case THERMAL_TYPE_EVERGREEN:
444 temp = evergreen_get_temp(rdev);
445 break;
446 default:
447 temp = 0;
448 break;
449 }
450
451 return snprintf(buf, PAGE_SIZE, "%d\n", temp);
452}
453
454static ssize_t radeon_hwmon_show_name(struct device *dev,
455 struct device_attribute *attr,
456 char *buf)
457{
458 return sprintf(buf, "radeon\n");
459}
460
461static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0);
462static SENSOR_DEVICE_ATTR(name, S_IRUGO, radeon_hwmon_show_name, NULL, 0);
463
464static struct attribute *hwmon_attributes[] = {
465 &sensor_dev_attr_temp1_input.dev_attr.attr,
466 &sensor_dev_attr_name.dev_attr.attr,
467 NULL
468};
469
470static const struct attribute_group hwmon_attrgroup = {
471 .attrs = hwmon_attributes,
472};
473
474static void radeon_hwmon_init(struct radeon_device *rdev)
475{
476 int err;
477
478 rdev->pm.int_hwmon_dev = NULL;
479
480 switch (rdev->pm.int_thermal_type) {
481 case THERMAL_TYPE_RV6XX:
482 case THERMAL_TYPE_RV770:
483 case THERMAL_TYPE_EVERGREEN:
484 rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
485 dev_set_drvdata(rdev->pm.int_hwmon_dev, rdev->ddev);
486 err = sysfs_create_group(&rdev->pm.int_hwmon_dev->kobj,
487 &hwmon_attrgroup);
488 if (err)
489 DRM_ERROR("Unable to create hwmon sysfs file: %d\n", err);
490 break;
491 default:
492 break;
493 }
494}
495
496static void radeon_hwmon_fini(struct radeon_device *rdev)
497{
498 if (rdev->pm.int_hwmon_dev) {
499 sysfs_remove_group(&rdev->pm.int_hwmon_dev->kobj, &hwmon_attrgroup);
500 hwmon_device_unregister(rdev->pm.int_hwmon_dev);
501 }
502}
503
426void radeon_pm_suspend(struct radeon_device *rdev) 504void radeon_pm_suspend(struct radeon_device *rdev)
427{ 505{
428 bool flush_wq = false; 506 bool flush_wq = false;
@@ -470,6 +548,7 @@ int radeon_pm_init(struct radeon_device *rdev)
470 rdev->pm.dynpm_can_downclock = true; 548 rdev->pm.dynpm_can_downclock = true;
471 rdev->pm.current_sclk = rdev->clock.default_sclk; 549 rdev->pm.current_sclk = rdev->clock.default_sclk;
472 rdev->pm.current_mclk = rdev->clock.default_mclk; 550 rdev->pm.current_mclk = rdev->clock.default_mclk;
551 rdev->pm.int_thermal_type = THERMAL_TYPE_NONE;
473 552
474 if (rdev->bios) { 553 if (rdev->bios) {
475 if (rdev->is_atom_bios) 554 if (rdev->is_atom_bios)
@@ -480,6 +559,8 @@ int radeon_pm_init(struct radeon_device *rdev)
480 radeon_pm_init_profile(rdev); 559 radeon_pm_init_profile(rdev);
481 } 560 }
482 561
562 /* set up the internal thermal sensor if applicable */
563 radeon_hwmon_init(rdev);
483 if (rdev->pm.num_power_states > 1) { 564 if (rdev->pm.num_power_states > 1) {
484 /* where's the best place to put these? */ 565 /* where's the best place to put these? */
485 ret = device_create_file(rdev->dev, &dev_attr_power_profile); 566 ret = device_create_file(rdev->dev, &dev_attr_power_profile);
@@ -535,6 +616,7 @@ void radeon_pm_fini(struct radeon_device *rdev)
535#endif 616#endif
536 } 617 }
537 618
619 radeon_hwmon_fini(rdev);
538 if (rdev->pm.i2c_bus) 620 if (rdev->pm.i2c_bus)
539 radeon_i2c_destroy(rdev->pm.i2c_bus); 621 radeon_i2c_destroy(rdev->pm.i2c_bus);
540} 622}