diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 140 |
1 files changed, 116 insertions, 24 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index b076b96f8b6c..a6b2aca36b47 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -67,41 +67,133 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
67 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | 67 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
68 | */ | 68 | */ |
69 | 69 | ||
70 | void r100_get_power_state(struct radeon_device *rdev, | ||
71 | enum radeon_pm_action action) | ||
72 | { | ||
73 | int i; | ||
74 | rdev->pm.can_upclock = true; | ||
75 | rdev->pm.can_downclock = true; | ||
76 | |||
77 | switch (action) { | ||
78 | case PM_ACTION_MINIMUM: | ||
79 | rdev->pm.requested_power_state_index = 0; | ||
80 | rdev->pm.can_downclock = false; | ||
81 | break; | ||
82 | case PM_ACTION_DOWNCLOCK: | ||
83 | if (rdev->pm.current_power_state_index == 0) { | ||
84 | rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; | ||
85 | rdev->pm.can_downclock = false; | ||
86 | } else { | ||
87 | if (rdev->pm.active_crtc_count > 1) { | ||
88 | for (i = 0; i < rdev->pm.num_power_states; i++) { | ||
89 | if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY) | ||
90 | continue; | ||
91 | else if (i >= rdev->pm.current_power_state_index) { | ||
92 | rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; | ||
93 | break; | ||
94 | } else { | ||
95 | rdev->pm.requested_power_state_index = i; | ||
96 | break; | ||
97 | } | ||
98 | } | ||
99 | } else | ||
100 | rdev->pm.requested_power_state_index = | ||
101 | rdev->pm.current_power_state_index - 1; | ||
102 | } | ||
103 | break; | ||
104 | case PM_ACTION_UPCLOCK: | ||
105 | if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) { | ||
106 | rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; | ||
107 | rdev->pm.can_upclock = false; | ||
108 | } else { | ||
109 | if (rdev->pm.active_crtc_count > 1) { | ||
110 | for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) { | ||
111 | if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY) | ||
112 | continue; | ||
113 | else if (i <= rdev->pm.current_power_state_index) { | ||
114 | rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; | ||
115 | break; | ||
116 | } else { | ||
117 | rdev->pm.requested_power_state_index = i; | ||
118 | break; | ||
119 | } | ||
120 | } | ||
121 | } else | ||
122 | rdev->pm.requested_power_state_index = | ||
123 | rdev->pm.current_power_state_index + 1; | ||
124 | } | ||
125 | break; | ||
126 | case PM_ACTION_NONE: | ||
127 | default: | ||
128 | DRM_ERROR("Requested mode for not defined action\n"); | ||
129 | return; | ||
130 | } | ||
131 | /* only one clock mode per power state */ | ||
132 | rdev->pm.requested_clock_mode_index = 0; | ||
133 | |||
134 | DRM_INFO("Requested: e: %d m: %d p: %d\n", | ||
135 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. | ||
136 | clock_info[rdev->pm.requested_clock_mode_index].sclk, | ||
137 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. | ||
138 | clock_info[rdev->pm.requested_clock_mode_index].mclk, | ||
139 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. | ||
140 | non_clock_info.pcie_lanes); | ||
141 | } | ||
142 | |||
70 | void r100_set_power_state(struct radeon_device *rdev) | 143 | void r100_set_power_state(struct radeon_device *rdev) |
71 | { | 144 | { |
72 | /* if *_clock_mode are the same, *_power_state are as well */ | 145 | u32 sclk, mclk; |
73 | if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode) | 146 | |
147 | if (rdev->pm.current_power_state_index == rdev->pm.requested_power_state_index) | ||
74 | return; | 148 | return; |
75 | 149 | ||
76 | DRM_INFO("Setting: e: %d m: %d p: %d\n", | 150 | if (radeon_gui_idle(rdev)) { |
77 | rdev->pm.requested_clock_mode->sclk, | ||
78 | rdev->pm.requested_clock_mode->mclk, | ||
79 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); | ||
80 | 151 | ||
81 | /* set pcie lanes */ | 152 | sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
82 | /* TODO */ | 153 | clock_info[rdev->pm.requested_clock_mode_index].sclk; |
154 | if (sclk > rdev->clock.default_sclk) | ||
155 | sclk = rdev->clock.default_sclk; | ||
83 | 156 | ||
84 | /* set voltage */ | 157 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
85 | /* TODO */ | 158 | clock_info[rdev->pm.requested_clock_mode_index].mclk; |
159 | if (mclk > rdev->clock.default_mclk) | ||
160 | mclk = rdev->clock.default_mclk; | ||
161 | /* don't change the mclk with multiple crtcs */ | ||
162 | if (rdev->pm.active_crtc_count > 1) | ||
163 | mclk = rdev->clock.default_mclk; | ||
86 | 164 | ||
87 | /* set engine clock */ | 165 | /* set pcie lanes */ |
88 | radeon_sync_with_vblank(rdev); | 166 | /* TODO */ |
89 | radeon_pm_debug_check_in_vbl(rdev, false); | 167 | |
90 | radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); | 168 | /* set voltage */ |
91 | radeon_pm_debug_check_in_vbl(rdev, true); | 169 | /* TODO */ |
170 | |||
171 | /* set engine clock */ | ||
172 | if (sclk != rdev->pm.current_sclk) { | ||
173 | radeon_sync_with_vblank(rdev); | ||
174 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
175 | radeon_set_engine_clock(rdev, sclk); | ||
176 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
177 | rdev->pm.current_sclk = sclk; | ||
178 | DRM_INFO("Setting: e: %d\n", sclk); | ||
179 | } | ||
92 | 180 | ||
93 | #if 0 | 181 | #if 0 |
94 | /* set memory clock */ | 182 | /* set memory clock */ |
95 | if (rdev->asic->set_memory_clock) { | 183 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { |
96 | radeon_sync_with_vblank(rdev); | 184 | radeon_sync_with_vblank(rdev); |
97 | radeon_pm_debug_check_in_vbl(rdev, false); | 185 | radeon_pm_debug_check_in_vbl(rdev, false); |
98 | radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk); | 186 | radeon_set_memory_clock(rdev, mclk); |
99 | radeon_pm_debug_check_in_vbl(rdev, true); | 187 | radeon_pm_debug_check_in_vbl(rdev, true); |
100 | } | 188 | rdev->pm.current_mclk = mclk; |
189 | DRM_INFO("Setting: m: %d\n", mclk); | ||
190 | } | ||
101 | #endif | 191 | #endif |
102 | 192 | ||
103 | rdev->pm.current_power_state = rdev->pm.requested_power_state; | 193 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; |
104 | rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; | 194 | rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; |
195 | } else | ||
196 | DRM_INFO("GUI not idle!!!\n"); | ||
105 | } | 197 | } |
106 | 198 | ||
107 | bool r100_gui_idle(struct radeon_device *rdev) | 199 | bool r100_gui_idle(struct radeon_device *rdev) |