diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 6fac8efe8340..2bdae61c0ac0 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -361,6 +361,11 @@ static ssize_t radeon_set_pm_profile(struct device *dev, | |||
361 | struct drm_device *ddev = dev_get_drvdata(dev); | 361 | struct drm_device *ddev = dev_get_drvdata(dev); |
362 | struct radeon_device *rdev = ddev->dev_private; | 362 | struct radeon_device *rdev = ddev->dev_private; |
363 | 363 | ||
364 | /* Can't set profile when the card is off */ | ||
365 | if ((rdev->flags & RADEON_IS_PX) && | ||
366 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | ||
367 | return -EINVAL; | ||
368 | |||
364 | mutex_lock(&rdev->pm.mutex); | 369 | mutex_lock(&rdev->pm.mutex); |
365 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { | 370 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { |
366 | if (strncmp("default", buf, strlen("default")) == 0) | 371 | if (strncmp("default", buf, strlen("default")) == 0) |
@@ -409,6 +414,13 @@ static ssize_t radeon_set_pm_method(struct device *dev, | |||
409 | struct drm_device *ddev = dev_get_drvdata(dev); | 414 | struct drm_device *ddev = dev_get_drvdata(dev); |
410 | struct radeon_device *rdev = ddev->dev_private; | 415 | struct radeon_device *rdev = ddev->dev_private; |
411 | 416 | ||
417 | /* Can't set method when the card is off */ | ||
418 | if ((rdev->flags & RADEON_IS_PX) && | ||
419 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) { | ||
420 | count = -EINVAL; | ||
421 | goto fail; | ||
422 | } | ||
423 | |||
412 | /* we don't support the legacy modes with dpm */ | 424 | /* we don't support the legacy modes with dpm */ |
413 | if (rdev->pm.pm_method == PM_METHOD_DPM) { | 425 | if (rdev->pm.pm_method == PM_METHOD_DPM) { |
414 | count = -EINVAL; | 426 | count = -EINVAL; |
@@ -446,6 +458,10 @@ static ssize_t radeon_get_dpm_state(struct device *dev, | |||
446 | struct radeon_device *rdev = ddev->dev_private; | 458 | struct radeon_device *rdev = ddev->dev_private; |
447 | enum radeon_pm_state_type pm = rdev->pm.dpm.user_state; | 459 | enum radeon_pm_state_type pm = rdev->pm.dpm.user_state; |
448 | 460 | ||
461 | if ((rdev->flags & RADEON_IS_PX) && | ||
462 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | ||
463 | return snprintf(buf, PAGE_SIZE, "off\n"); | ||
464 | |||
449 | return snprintf(buf, PAGE_SIZE, "%s\n", | 465 | return snprintf(buf, PAGE_SIZE, "%s\n", |
450 | (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : | 466 | (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : |
451 | (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); | 467 | (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); |
@@ -459,6 +475,11 @@ static ssize_t radeon_set_dpm_state(struct device *dev, | |||
459 | struct drm_device *ddev = dev_get_drvdata(dev); | 475 | struct drm_device *ddev = dev_get_drvdata(dev); |
460 | struct radeon_device *rdev = ddev->dev_private; | 476 | struct radeon_device *rdev = ddev->dev_private; |
461 | 477 | ||
478 | /* Can't set dpm state when the card is off */ | ||
479 | if ((rdev->flags & RADEON_IS_PX) && | ||
480 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | ||
481 | return -EINVAL; | ||
482 | |||
462 | mutex_lock(&rdev->pm.mutex); | 483 | mutex_lock(&rdev->pm.mutex); |
463 | if (strncmp("battery", buf, strlen("battery")) == 0) | 484 | if (strncmp("battery", buf, strlen("battery")) == 0) |
464 | rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY; | 485 | rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY; |
@@ -485,6 +506,10 @@ static ssize_t radeon_get_dpm_forced_performance_level(struct device *dev, | |||
485 | struct radeon_device *rdev = ddev->dev_private; | 506 | struct radeon_device *rdev = ddev->dev_private; |
486 | enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; | 507 | enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; |
487 | 508 | ||
509 | if ((rdev->flags & RADEON_IS_PX) && | ||
510 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | ||
511 | return snprintf(buf, PAGE_SIZE, "off\n"); | ||
512 | |||
488 | return snprintf(buf, PAGE_SIZE, "%s\n", | 513 | return snprintf(buf, PAGE_SIZE, "%s\n", |
489 | (level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" : | 514 | (level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" : |
490 | (level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); | 515 | (level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); |
@@ -500,6 +525,11 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev, | |||
500 | enum radeon_dpm_forced_level level; | 525 | enum radeon_dpm_forced_level level; |
501 | int ret = 0; | 526 | int ret = 0; |
502 | 527 | ||
528 | /* Can't force performance level when the card is off */ | ||
529 | if ((rdev->flags & RADEON_IS_PX) && | ||
530 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | ||
531 | return -EINVAL; | ||
532 | |||
503 | mutex_lock(&rdev->pm.mutex); | 533 | mutex_lock(&rdev->pm.mutex); |
504 | if (strncmp("low", buf, strlen("low")) == 0) { | 534 | if (strncmp("low", buf, strlen("low")) == 0) { |
505 | level = RADEON_DPM_FORCED_LEVEL_LOW; | 535 | level = RADEON_DPM_FORCED_LEVEL_LOW; |
@@ -538,8 +568,14 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, | |||
538 | char *buf) | 568 | char *buf) |
539 | { | 569 | { |
540 | struct radeon_device *rdev = dev_get_drvdata(dev); | 570 | struct radeon_device *rdev = dev_get_drvdata(dev); |
571 | struct drm_device *ddev = rdev->ddev; | ||
541 | int temp; | 572 | int temp; |
542 | 573 | ||
574 | /* Can't get temperature when the card is off */ | ||
575 | if ((rdev->flags & RADEON_IS_PX) && | ||
576 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | ||
577 | return -EINVAL; | ||
578 | |||
543 | if (rdev->asic->pm.get_temperature) | 579 | if (rdev->asic->pm.get_temperature) |
544 | temp = radeon_get_temperature(rdev); | 580 | temp = radeon_get_temperature(rdev); |
545 | else | 581 | else |
@@ -1068,7 +1104,6 @@ static void radeon_pm_resume_dpm(struct radeon_device *rdev) | |||
1068 | if (ret) | 1104 | if (ret) |
1069 | goto dpm_resume_fail; | 1105 | goto dpm_resume_fail; |
1070 | rdev->pm.dpm_enabled = true; | 1106 | rdev->pm.dpm_enabled = true; |
1071 | radeon_pm_compute_clocks(rdev); | ||
1072 | return; | 1107 | return; |
1073 | 1108 | ||
1074 | dpm_resume_fail: | 1109 | dpm_resume_fail: |
@@ -1300,6 +1335,7 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
1300 | case CHIP_KABINI: | 1335 | case CHIP_KABINI: |
1301 | case CHIP_KAVERI: | 1336 | case CHIP_KAVERI: |
1302 | case CHIP_HAWAII: | 1337 | case CHIP_HAWAII: |
1338 | case CHIP_MULLINS: | ||
1303 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ | 1339 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ |
1304 | if (!rdev->rlc_fw) | 1340 | if (!rdev->rlc_fw) |
1305 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1341 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
@@ -1613,8 +1649,12 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) | |||
1613 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1649 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
1614 | struct drm_device *dev = node->minor->dev; | 1650 | struct drm_device *dev = node->minor->dev; |
1615 | struct radeon_device *rdev = dev->dev_private; | 1651 | struct radeon_device *rdev = dev->dev_private; |
1652 | struct drm_device *ddev = rdev->ddev; | ||
1616 | 1653 | ||
1617 | if (rdev->pm.dpm_enabled) { | 1654 | if ((rdev->flags & RADEON_IS_PX) && |
1655 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) { | ||
1656 | seq_printf(m, "PX asic powered off\n"); | ||
1657 | } else if (rdev->pm.dpm_enabled) { | ||
1618 | mutex_lock(&rdev->pm.mutex); | 1658 | mutex_lock(&rdev->pm.mutex); |
1619 | if (rdev->asic->dpm.debugfs_print_current_performance_level) | 1659 | if (rdev->asic->dpm.debugfs_print_current_performance_level) |
1620 | radeon_dpm_debugfs_print_current_performance_level(rdev, m); | 1660 | radeon_dpm_debugfs_print_current_performance_level(rdev, m); |