@@ -67,41 +67,133 @@ MODULE_FIRMWARE(FIRMWARE_R520);
67
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
143
void r100_set_power_state (struct radeon_device * rdev )
71
144
{
72
- /* if *_clock_mode are the same, *_power_state are as well */
73
- if (rdev -> pm .requested_clock_mode == rdev -> pm .current_clock_mode )
145
+ u32 sclk , mclk ;
146
+
147
+ if (rdev -> pm .current_power_state_index == rdev -> pm .requested_power_state_index )
74
148
return ;
75
149
76
- DRM_INFO ("Setting: e: %d m: %d p: %d\n" ,
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 );
150
+ if (radeon_gui_idle (rdev )) {
80
151
81
- /* set pcie lanes */
82
- /* TODO */
152
+ sclk = rdev -> pm .power_state [rdev -> pm .requested_power_state_index ].
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 */
85
- /* TODO */
157
+ mclk = rdev -> pm .power_state [rdev -> pm .requested_power_state_index ].
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 */
88
- radeon_sync_with_vblank (rdev );
89
- radeon_pm_debug_check_in_vbl (rdev , false);
90
- radeon_set_engine_clock (rdev , rdev -> pm .requested_clock_mode -> sclk );
91
- radeon_pm_debug_check_in_vbl (rdev , true);
165
+ /* set pcie lanes */
166
+ /* TODO */
167
+
168
+ /* set voltage */
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
181
#if 0
94
- /* set memory clock */
95
- if (rdev -> asic -> set_memory_clock ) {
96
- radeon_sync_with_vblank (rdev );
97
- radeon_pm_debug_check_in_vbl (rdev , false);
98
- radeon_set_memory_clock (rdev , rdev -> pm .requested_clock_mode -> mclk );
99
- radeon_pm_debug_check_in_vbl (rdev , true);
100
- }
182
+ /* set memory clock */
183
+ if (rdev -> asic -> set_memory_clock && (mclk != rdev -> pm .current_mclk )) {
184
+ radeon_sync_with_vblank (rdev );
185
+ radeon_pm_debug_check_in_vbl (rdev , false);
186
+ radeon_set_memory_clock (rdev , mclk );
187
+ radeon_pm_debug_check_in_vbl (rdev , true);
188
+ rdev -> pm .current_mclk = mclk ;
189
+ DRM_INFO ("Setting: m: %d\n" , mclk );
190
+ }
101
191
#endif
102
192
103
- rdev -> pm .current_power_state = rdev -> pm .requested_power_state ;
104
- rdev -> pm .current_clock_mode = rdev -> pm .requested_clock_mode ;
193
+ rdev -> pm .current_power_state_index = rdev -> pm .requested_power_state_index ;
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
199
bool r100_gui_idle (struct radeon_device * rdev )
0 commit comments