diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-05-07 15:10:16 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-05-18 04:21:52 -0400 |
commit | ce8f53709bf440100cb9d31b1303291551cf517f (patch) | |
tree | 6785882522ae04486ae900b5c8dbc700dadad2f3 /drivers/gpu/drm/radeon/radeon.h | |
parent | d7311171c4cc8d6231427f7ac5056b939a184b80 (diff) |
drm/radeon/kms/pm: rework power management
- Separate dynpm and profile based power management methods. You can select the pm method
by echoing the selected method ("dynpm" or "profile") to power_method in sysfs.
- Expose basic 4 profile in profile method
"default" - default clocks
"auto" - select between low and high based on ac/dc state
"low" - DC, low power mode
"high" - AC, performance mode
The current base profile is "default", but it should switched to "auto" once we've tested
on more systems. Switching the state is a matter of echoing the requested profile to
power_profile in sysfs. The lowest power states are selected automatically when dpms turns
the monitors off in all states but default.
- Remove dynamic fence-based reclocking for the moment. We can revisit this later once we
have basic pm in.
- Move pm init/fini to modesetting path. pm is tightly coupled with display state. Make sure
display side is initialized before pm.
- Add pm suspend/resume functions to make sure pm state is properly reinitialized on resume.
- Remove dynpm module option. It's now selectable via sysfs.
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon.h')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 87 |
1 files changed, 57 insertions, 30 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 480a83ff54d..5c9ce2beaca 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -89,7 +89,6 @@ extern int radeon_testing; | |||
89 | extern int radeon_connector_table; | 89 | extern int radeon_connector_table; |
90 | extern int radeon_tv; | 90 | extern int radeon_tv; |
91 | extern int radeon_new_pll; | 91 | extern int radeon_new_pll; |
92 | extern int radeon_dynpm; | ||
93 | extern int radeon_audio; | 92 | extern int radeon_audio; |
94 | extern int radeon_disp_priority; | 93 | extern int radeon_disp_priority; |
95 | extern int radeon_hw_i2c; | 94 | extern int radeon_hw_i2c; |
@@ -173,11 +172,10 @@ struct radeon_clock { | |||
173 | int radeon_pm_init(struct radeon_device *rdev); | 172 | int radeon_pm_init(struct radeon_device *rdev); |
174 | void radeon_pm_fini(struct radeon_device *rdev); | 173 | void radeon_pm_fini(struct radeon_device *rdev); |
175 | void radeon_pm_compute_clocks(struct radeon_device *rdev); | 174 | void radeon_pm_compute_clocks(struct radeon_device *rdev); |
175 | void radeon_pm_suspend(struct radeon_device *rdev); | ||
176 | void radeon_pm_resume(struct radeon_device *rdev); | ||
176 | void radeon_combios_get_power_modes(struct radeon_device *rdev); | 177 | void radeon_combios_get_power_modes(struct radeon_device *rdev); |
177 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); | 178 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); |
178 | bool radeon_pm_in_vbl(struct radeon_device *rdev); | ||
179 | bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); | ||
180 | void radeon_sync_with_vblank(struct radeon_device *rdev); | ||
181 | 179 | ||
182 | /* | 180 | /* |
183 | * Fences. | 181 | * Fences. |
@@ -608,18 +606,24 @@ struct radeon_wb { | |||
608 | * Equation between gpu/memory clock and available bandwidth is hw dependent | 606 | * Equation between gpu/memory clock and available bandwidth is hw dependent |
609 | * (type of memory, bus size, efficiency, ...) | 607 | * (type of memory, bus size, efficiency, ...) |
610 | */ | 608 | */ |
611 | enum radeon_pm_state { | 609 | |
612 | PM_STATE_DISABLED, | 610 | enum radeon_pm_method { |
613 | PM_STATE_MINIMUM, | 611 | PM_METHOD_PROFILE, |
614 | PM_STATE_PAUSED, | 612 | PM_METHOD_DYNPM, |
615 | PM_STATE_ACTIVE | 613 | }; |
614 | |||
615 | enum radeon_dynpm_state { | ||
616 | DYNPM_STATE_DISABLED, | ||
617 | DYNPM_STATE_MINIMUM, | ||
618 | DYNPM_STATE_PAUSED, | ||
619 | DYNPM_STATE_ACTIVE | ||
616 | }; | 620 | }; |
617 | enum radeon_pm_action { | 621 | enum radeon_dynpm_action { |
618 | PM_ACTION_NONE, | 622 | DYNPM_ACTION_NONE, |
619 | PM_ACTION_MINIMUM, | 623 | DYNPM_ACTION_MINIMUM, |
620 | PM_ACTION_DOWNCLOCK, | 624 | DYNPM_ACTION_DOWNCLOCK, |
621 | PM_ACTION_UPCLOCK, | 625 | DYNPM_ACTION_UPCLOCK, |
622 | PM_ACTION_DEFAULT | 626 | DYNPM_ACTION_DEFAULT |
623 | }; | 627 | }; |
624 | 628 | ||
625 | enum radeon_voltage_type { | 629 | enum radeon_voltage_type { |
@@ -637,11 +641,25 @@ enum radeon_pm_state_type { | |||
637 | POWER_STATE_TYPE_PERFORMANCE, | 641 | POWER_STATE_TYPE_PERFORMANCE, |
638 | }; | 642 | }; |
639 | 643 | ||
640 | enum radeon_pm_clock_mode_type { | 644 | enum radeon_pm_profile_type { |
641 | POWER_MODE_TYPE_DEFAULT, | 645 | PM_PROFILE_DEFAULT, |
642 | POWER_MODE_TYPE_LOW, | 646 | PM_PROFILE_AUTO, |
643 | POWER_MODE_TYPE_MID, | 647 | PM_PROFILE_LOW, |
644 | POWER_MODE_TYPE_HIGH, | 648 | PM_PROFILE_HIGH, |
649 | }; | ||
650 | |||
651 | #define PM_PROFILE_DEFAULT_IDX 0 | ||
652 | #define PM_PROFILE_LOW_SH_IDX 1 | ||
653 | #define PM_PROFILE_HIGH_SH_IDX 2 | ||
654 | #define PM_PROFILE_LOW_MH_IDX 3 | ||
655 | #define PM_PROFILE_HIGH_MH_IDX 4 | ||
656 | #define PM_PROFILE_MAX 5 | ||
657 | |||
658 | struct radeon_pm_profile { | ||
659 | int dpms_off_ps_idx; | ||
660 | int dpms_on_ps_idx; | ||
661 | int dpms_off_cm_idx; | ||
662 | int dpms_on_cm_idx; | ||
645 | }; | 663 | }; |
646 | 664 | ||
647 | struct radeon_voltage { | 665 | struct radeon_voltage { |
@@ -696,12 +714,6 @@ struct radeon_power_state { | |||
696 | 714 | ||
697 | struct radeon_pm { | 715 | struct radeon_pm { |
698 | struct mutex mutex; | 716 | struct mutex mutex; |
699 | struct delayed_work idle_work; | ||
700 | enum radeon_pm_state state; | ||
701 | enum radeon_pm_action planned_action; | ||
702 | unsigned long action_timeout; | ||
703 | bool can_upclock; | ||
704 | bool can_downclock; | ||
705 | u32 active_crtcs; | 717 | u32 active_crtcs; |
706 | int active_crtc_count; | 718 | int active_crtc_count; |
707 | int req_vblank; | 719 | int req_vblank; |
@@ -731,6 +743,19 @@ struct radeon_pm { | |||
731 | u32 current_sclk; | 743 | u32 current_sclk; |
732 | u32 current_mclk; | 744 | u32 current_mclk; |
733 | struct radeon_i2c_chan *i2c_bus; | 745 | struct radeon_i2c_chan *i2c_bus; |
746 | /* selected pm method */ | ||
747 | enum radeon_pm_method pm_method; | ||
748 | /* dynpm power management */ | ||
749 | struct delayed_work dynpm_idle_work; | ||
750 | enum radeon_dynpm_state dynpm_state; | ||
751 | enum radeon_dynpm_action dynpm_planned_action; | ||
752 | unsigned long dynpm_action_timeout; | ||
753 | bool dynpm_can_upclock; | ||
754 | bool dynpm_can_downclock; | ||
755 | /* profile-based power management */ | ||
756 | enum radeon_pm_profile_type profile; | ||
757 | int profile_index; | ||
758 | struct radeon_pm_profile profiles[PM_PROFILE_MAX]; | ||
734 | }; | 759 | }; |
735 | 760 | ||
736 | 761 | ||
@@ -819,11 +844,12 @@ struct radeon_asic { | |||
819 | */ | 844 | */ |
820 | void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo); | 845 | void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo); |
821 | bool (*gui_idle)(struct radeon_device *rdev); | 846 | bool (*gui_idle)(struct radeon_device *rdev); |
822 | void (*get_power_state)(struct radeon_device *rdev, enum radeon_pm_action action); | 847 | /* power management */ |
823 | void (*set_power_state)(struct radeon_device *rdev, bool static_switch); | ||
824 | void (*pm_misc)(struct radeon_device *rdev); | 848 | void (*pm_misc)(struct radeon_device *rdev); |
825 | void (*pm_prepare)(struct radeon_device *rdev); | 849 | void (*pm_prepare)(struct radeon_device *rdev); |
826 | void (*pm_finish)(struct radeon_device *rdev); | 850 | void (*pm_finish)(struct radeon_device *rdev); |
851 | void (*pm_init_profile)(struct radeon_device *rdev); | ||
852 | void (*pm_get_dynpm_state)(struct radeon_device *rdev); | ||
827 | }; | 853 | }; |
828 | 854 | ||
829 | /* | 855 | /* |
@@ -1041,6 +1067,7 @@ struct radeon_device { | |||
1041 | uint8_t audio_category_code; | 1067 | uint8_t audio_category_code; |
1042 | 1068 | ||
1043 | bool powered_down; | 1069 | bool powered_down; |
1070 | struct notifier_block acpi_nb; | ||
1044 | }; | 1071 | }; |
1045 | 1072 | ||
1046 | int radeon_device_init(struct radeon_device *rdev, | 1073 | int radeon_device_init(struct radeon_device *rdev, |
@@ -1232,11 +1259,11 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
1232 | #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) | 1259 | #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) |
1233 | #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) | 1260 | #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) |
1234 | #define radeon_gui_idle(rdev) (rdev)->asic->gui_idle((rdev)) | 1261 | #define radeon_gui_idle(rdev) (rdev)->asic->gui_idle((rdev)) |
1235 | #define radeon_get_power_state(rdev, a) (rdev)->asic->get_power_state((rdev), (a)) | ||
1236 | #define radeon_set_power_state(rdev, s) (rdev)->asic->set_power_state((rdev), (s)) | ||
1237 | #define radeon_pm_misc(rdev) (rdev)->asic->pm_misc((rdev)) | 1262 | #define radeon_pm_misc(rdev) (rdev)->asic->pm_misc((rdev)) |
1238 | #define radeon_pm_prepare(rdev) (rdev)->asic->pm_prepare((rdev)) | 1263 | #define radeon_pm_prepare(rdev) (rdev)->asic->pm_prepare((rdev)) |
1239 | #define radeon_pm_finish(rdev) (rdev)->asic->pm_finish((rdev)) | 1264 | #define radeon_pm_finish(rdev) (rdev)->asic->pm_finish((rdev)) |
1265 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm_init_profile((rdev)) | ||
1266 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm_get_dynpm_state((rdev)) | ||
1240 | 1267 | ||
1241 | /* Common functions */ | 1268 | /* Common functions */ |
1242 | /* AGP */ | 1269 | /* AGP */ |