diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 436 |
1 files changed, 431 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 46146c6a2a06..a4b57493aa78 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -18,21 +18,441 @@ | |||
18 | * OTHER DEALINGS IN THE SOFTWARE. | 18 | * OTHER DEALINGS IN THE SOFTWARE. |
19 | * | 19 | * |
20 | * Authors: Rafał Miłecki <zajec5@gmail.com> | 20 | * Authors: Rafał Miłecki <zajec5@gmail.com> |
21 | * Alex Deucher <alexdeucher@gmail.com> | ||
21 | */ | 22 | */ |
22 | #include "drmP.h" | 23 | #include "drmP.h" |
23 | #include "radeon.h" | 24 | #include "radeon.h" |
25 | #include "avivod.h" | ||
24 | 26 | ||
25 | int radeon_debugfs_pm_init(struct radeon_device *rdev); | 27 | #define RADEON_IDLE_LOOP_MS 100 |
28 | #define RADEON_RECLOCK_DELAY_MS 200 | ||
29 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 | ||
30 | |||
31 | static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); | ||
32 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); | ||
33 | static void radeon_pm_set_clocks(struct radeon_device *rdev); | ||
34 | static void radeon_pm_idle_work_handler(struct work_struct *work); | ||
35 | static int radeon_debugfs_pm_init(struct radeon_device *rdev); | ||
36 | |||
37 | static const char *pm_state_names[4] = { | ||
38 | "PM_STATE_DISABLED", | ||
39 | "PM_STATE_MINIMUM", | ||
40 | "PM_STATE_PAUSED", | ||
41 | "PM_STATE_ACTIVE" | ||
42 | }; | ||
43 | |||
44 | static const char *pm_state_types[5] = { | ||
45 | "Default", | ||
46 | "Powersave", | ||
47 | "Battery", | ||
48 | "Balanced", | ||
49 | "Performance", | ||
50 | }; | ||
51 | |||
52 | static void radeon_print_power_mode_info(struct radeon_device *rdev) | ||
53 | { | ||
54 | int i, j; | ||
55 | bool is_default; | ||
56 | |||
57 | DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states); | ||
58 | for (i = 0; i < rdev->pm.num_power_states; i++) { | ||
59 | if (rdev->pm.default_power_state == &rdev->pm.power_state[i]) | ||
60 | is_default = true; | ||
61 | else | ||
62 | is_default = false; | ||
63 | DRM_INFO("State %d %s %s\n", i, | ||
64 | pm_state_types[rdev->pm.power_state[i].type], | ||
65 | is_default ? "(default)" : ""); | ||
66 | if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP)) | ||
67 | DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].non_clock_info.pcie_lanes); | ||
68 | DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes); | ||
69 | for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) { | ||
70 | if (rdev->flags & RADEON_IS_IGP) | ||
71 | DRM_INFO("\t\t%d engine: %d\n", | ||
72 | j, | ||
73 | rdev->pm.power_state[i].clock_info[j].sclk * 10); | ||
74 | else | ||
75 | DRM_INFO("\t\t%d engine/memory: %d/%d\n", | ||
76 | j, | ||
77 | rdev->pm.power_state[i].clock_info[j].sclk * 10, | ||
78 | rdev->pm.power_state[i].clock_info[j].mclk * 10); | ||
79 | } | ||
80 | } | ||
81 | } | ||
82 | |||
83 | static struct radeon_power_state * radeon_pick_power_state(struct radeon_device *rdev, | ||
84 | enum radeon_pm_state_type type) | ||
85 | { | ||
86 | int i, j; | ||
87 | enum radeon_pm_state_type wanted_types[2]; | ||
88 | int wanted_count; | ||
89 | |||
90 | switch (type) { | ||
91 | case POWER_STATE_TYPE_DEFAULT: | ||
92 | default: | ||
93 | return rdev->pm.default_power_state; | ||
94 | case POWER_STATE_TYPE_POWERSAVE: | ||
95 | if (rdev->flags & RADEON_IS_MOBILITY) { | ||
96 | wanted_types[0] = POWER_STATE_TYPE_POWERSAVE; | ||
97 | wanted_types[1] = POWER_STATE_TYPE_BATTERY; | ||
98 | wanted_count = 2; | ||
99 | } else { | ||
100 | wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE; | ||
101 | wanted_count = 1; | ||
102 | } | ||
103 | break; | ||
104 | case POWER_STATE_TYPE_BATTERY: | ||
105 | if (rdev->flags & RADEON_IS_MOBILITY) { | ||
106 | wanted_types[0] = POWER_STATE_TYPE_BATTERY; | ||
107 | wanted_types[1] = POWER_STATE_TYPE_POWERSAVE; | ||
108 | wanted_count = 2; | ||
109 | } else { | ||
110 | wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE; | ||
111 | wanted_count = 1; | ||
112 | } | ||
113 | break; | ||
114 | case POWER_STATE_TYPE_BALANCED: | ||
115 | case POWER_STATE_TYPE_PERFORMANCE: | ||
116 | wanted_types[0] = type; | ||
117 | wanted_count = 1; | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | for (i = 0; i < wanted_count; i++) { | ||
122 | for (j = 0; j < rdev->pm.num_power_states; j++) { | ||
123 | if (rdev->pm.power_state[j].type == wanted_types[i]) | ||
124 | return &rdev->pm.power_state[j]; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | return rdev->pm.default_power_state; | ||
129 | } | ||
130 | |||
131 | static struct radeon_pm_clock_info * radeon_pick_clock_mode(struct radeon_device *rdev, | ||
132 | struct radeon_power_state *power_state, | ||
133 | enum radeon_pm_clock_mode_type type) | ||
134 | { | ||
135 | switch (type) { | ||
136 | case POWER_MODE_TYPE_DEFAULT: | ||
137 | default: | ||
138 | return power_state->default_clock_mode; | ||
139 | case POWER_MODE_TYPE_LOW: | ||
140 | return &power_state->clock_info[0]; | ||
141 | case POWER_MODE_TYPE_MID: | ||
142 | if (power_state->num_clock_modes > 2) | ||
143 | return &power_state->clock_info[1]; | ||
144 | else | ||
145 | return &power_state->clock_info[0]; | ||
146 | break; | ||
147 | case POWER_MODE_TYPE_HIGH: | ||
148 | return &power_state->clock_info[power_state->num_clock_modes - 1]; | ||
149 | } | ||
150 | |||
151 | } | ||
152 | |||
153 | static void radeon_get_power_state(struct radeon_device *rdev, | ||
154 | enum radeon_pm_action action) | ||
155 | { | ||
156 | switch (action) { | ||
157 | case PM_ACTION_MINIMUM: | ||
158 | rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_BATTERY); | ||
159 | rdev->pm.requested_clock_mode = | ||
160 | radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_LOW); | ||
161 | break; | ||
162 | case PM_ACTION_DOWNCLOCK: | ||
163 | rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_POWERSAVE); | ||
164 | rdev->pm.requested_clock_mode = | ||
165 | radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_MID); | ||
166 | break; | ||
167 | case PM_ACTION_UPCLOCK: | ||
168 | rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_DEFAULT); | ||
169 | rdev->pm.requested_clock_mode = | ||
170 | radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_HIGH); | ||
171 | break; | ||
172 | case PM_ACTION_NONE: | ||
173 | default: | ||
174 | DRM_ERROR("Requested mode for not defined action\n"); | ||
175 | return; | ||
176 | } | ||
177 | DRM_INFO("Requested: e: %d m: %d p: %d\n", | ||
178 | rdev->pm.requested_clock_mode->sclk, | ||
179 | rdev->pm.requested_clock_mode->mclk, | ||
180 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); | ||
181 | } | ||
182 | |||
183 | static inline void radeon_sync_with_vblank(struct radeon_device *rdev) | ||
184 | { | ||
185 | if (rdev->pm.active_crtcs) { | ||
186 | rdev->pm.vblank_sync = false; | ||
187 | wait_event_timeout( | ||
188 | rdev->irq.vblank_queue, rdev->pm.vblank_sync, | ||
189 | msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | static void radeon_set_power_state(struct radeon_device *rdev) | ||
194 | { | ||
195 | /* if *_clock_mode are the same, *_power_state are as well */ | ||
196 | if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode) | ||
197 | return; | ||
198 | |||
199 | DRM_INFO("Setting: e: %d m: %d p: %d\n", | ||
200 | rdev->pm.requested_clock_mode->sclk, | ||
201 | rdev->pm.requested_clock_mode->mclk, | ||
202 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); | ||
203 | |||
204 | /* set pcie lanes */ | ||
205 | /* TODO */ | ||
206 | |||
207 | /* set voltage */ | ||
208 | /* TODO */ | ||
209 | |||
210 | /* set engine clock */ | ||
211 | radeon_sync_with_vblank(rdev); | ||
212 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
213 | radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); | ||
214 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
215 | |||
216 | #if 0 | ||
217 | /* set memory clock */ | ||
218 | if (rdev->asic->set_memory_clock) { | ||
219 | radeon_sync_with_vblank(rdev); | ||
220 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
221 | radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk); | ||
222 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
223 | } | ||
224 | #endif | ||
225 | |||
226 | rdev->pm.current_power_state = rdev->pm.requested_power_state; | ||
227 | rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; | ||
228 | } | ||
26 | 229 | ||
27 | int radeon_pm_init(struct radeon_device *rdev) | 230 | int radeon_pm_init(struct radeon_device *rdev) |
28 | { | 231 | { |
232 | rdev->pm.state = PM_STATE_DISABLED; | ||
233 | rdev->pm.planned_action = PM_ACTION_NONE; | ||
234 | rdev->pm.downclocked = false; | ||
235 | |||
236 | if (rdev->bios) { | ||
237 | if (rdev->is_atom_bios) | ||
238 | radeon_atombios_get_power_modes(rdev); | ||
239 | else | ||
240 | radeon_combios_get_power_modes(rdev); | ||
241 | radeon_print_power_mode_info(rdev); | ||
242 | } | ||
243 | |||
29 | if (radeon_debugfs_pm_init(rdev)) { | 244 | if (radeon_debugfs_pm_init(rdev)) { |
30 | DRM_ERROR("Failed to register debugfs file for CP !\n"); | 245 | DRM_ERROR("Failed to register debugfs file for PM!\n"); |
246 | } | ||
247 | |||
248 | INIT_DELAYED_WORK(&rdev->pm.idle_work, radeon_pm_idle_work_handler); | ||
249 | |||
250 | if (radeon_dynpm != -1 && radeon_dynpm) { | ||
251 | rdev->pm.state = PM_STATE_PAUSED; | ||
252 | DRM_INFO("radeon: dynamic power management enabled\n"); | ||
31 | } | 253 | } |
32 | 254 | ||
255 | DRM_INFO("radeon: power management initialized\n"); | ||
256 | |||
33 | return 0; | 257 | return 0; |
34 | } | 258 | } |
35 | 259 | ||
260 | void radeon_pm_fini(struct radeon_device *rdev) | ||
261 | { | ||
262 | if (rdev->pm.i2c_bus) | ||
263 | radeon_i2c_destroy(rdev->pm.i2c_bus); | ||
264 | } | ||
265 | |||
266 | void radeon_pm_compute_clocks(struct radeon_device *rdev) | ||
267 | { | ||
268 | struct drm_device *ddev = rdev->ddev; | ||
269 | struct drm_connector *connector; | ||
270 | struct radeon_crtc *radeon_crtc; | ||
271 | int count = 0; | ||
272 | |||
273 | if (rdev->pm.state == PM_STATE_DISABLED) | ||
274 | return; | ||
275 | |||
276 | mutex_lock(&rdev->pm.mutex); | ||
277 | |||
278 | rdev->pm.active_crtcs = 0; | ||
279 | list_for_each_entry(connector, | ||
280 | &ddev->mode_config.connector_list, head) { | ||
281 | if (connector->encoder && | ||
282 | connector->encoder->crtc && | ||
283 | connector->dpms != DRM_MODE_DPMS_OFF) { | ||
284 | radeon_crtc = to_radeon_crtc(connector->encoder->crtc); | ||
285 | rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); | ||
286 | ++count; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | if (count > 1) { | ||
291 | if (rdev->pm.state == PM_STATE_ACTIVE) { | ||
292 | cancel_delayed_work(&rdev->pm.idle_work); | ||
293 | |||
294 | rdev->pm.state = PM_STATE_PAUSED; | ||
295 | rdev->pm.planned_action = PM_ACTION_UPCLOCK; | ||
296 | if (rdev->pm.downclocked) | ||
297 | radeon_pm_set_clocks(rdev); | ||
298 | |||
299 | DRM_DEBUG("radeon: dynamic power management deactivated\n"); | ||
300 | } | ||
301 | } else if (count == 1) { | ||
302 | /* TODO: Increase clocks if needed for current mode */ | ||
303 | |||
304 | if (rdev->pm.state == PM_STATE_MINIMUM) { | ||
305 | rdev->pm.state = PM_STATE_ACTIVE; | ||
306 | rdev->pm.planned_action = PM_ACTION_UPCLOCK; | ||
307 | radeon_pm_set_clocks(rdev); | ||
308 | |||
309 | queue_delayed_work(rdev->wq, &rdev->pm.idle_work, | ||
310 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | ||
311 | } | ||
312 | else if (rdev->pm.state == PM_STATE_PAUSED) { | ||
313 | rdev->pm.state = PM_STATE_ACTIVE; | ||
314 | queue_delayed_work(rdev->wq, &rdev->pm.idle_work, | ||
315 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | ||
316 | DRM_DEBUG("radeon: dynamic power management activated\n"); | ||
317 | } | ||
318 | } | ||
319 | else { /* count == 0 */ | ||
320 | if (rdev->pm.state != PM_STATE_MINIMUM) { | ||
321 | cancel_delayed_work(&rdev->pm.idle_work); | ||
322 | |||
323 | rdev->pm.state = PM_STATE_MINIMUM; | ||
324 | rdev->pm.planned_action = PM_ACTION_MINIMUM; | ||
325 | radeon_pm_set_clocks(rdev); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | mutex_unlock(&rdev->pm.mutex); | ||
330 | } | ||
331 | |||
332 | static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) | ||
333 | { | ||
334 | u32 stat_crtc1 = 0, stat_crtc2 = 0; | ||
335 | bool in_vbl = true; | ||
336 | |||
337 | if (ASIC_IS_AVIVO(rdev)) { | ||
338 | if (rdev->pm.active_crtcs & (1 << 0)) { | ||
339 | stat_crtc1 = RREG32(D1CRTC_STATUS); | ||
340 | if (!(stat_crtc1 & 1)) | ||
341 | in_vbl = false; | ||
342 | } | ||
343 | if (rdev->pm.active_crtcs & (1 << 1)) { | ||
344 | stat_crtc2 = RREG32(D2CRTC_STATUS); | ||
345 | if (!(stat_crtc2 & 1)) | ||
346 | in_vbl = false; | ||
347 | } | ||
348 | } | ||
349 | if (in_vbl == false) | ||
350 | DRM_INFO("not in vbl for pm change %08x %08x at %s\n", stat_crtc1, | ||
351 | stat_crtc2, finish ? "exit" : "entry"); | ||
352 | return in_vbl; | ||
353 | } | ||
354 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev) | ||
355 | { | ||
356 | /*radeon_fence_wait_last(rdev);*/ | ||
357 | switch (rdev->pm.planned_action) { | ||
358 | case PM_ACTION_UPCLOCK: | ||
359 | rdev->pm.downclocked = false; | ||
360 | break; | ||
361 | case PM_ACTION_DOWNCLOCK: | ||
362 | rdev->pm.downclocked = true; | ||
363 | break; | ||
364 | case PM_ACTION_MINIMUM: | ||
365 | break; | ||
366 | case PM_ACTION_NONE: | ||
367 | DRM_ERROR("%s: PM_ACTION_NONE\n", __func__); | ||
368 | break; | ||
369 | } | ||
370 | |||
371 | radeon_set_power_state(rdev); | ||
372 | rdev->pm.planned_action = PM_ACTION_NONE; | ||
373 | } | ||
374 | |||
375 | static void radeon_pm_set_clocks(struct radeon_device *rdev) | ||
376 | { | ||
377 | radeon_get_power_state(rdev, rdev->pm.planned_action); | ||
378 | mutex_lock(&rdev->cp.mutex); | ||
379 | |||
380 | if (rdev->pm.active_crtcs & (1 << 0)) { | ||
381 | rdev->pm.req_vblank |= (1 << 0); | ||
382 | drm_vblank_get(rdev->ddev, 0); | ||
383 | } | ||
384 | if (rdev->pm.active_crtcs & (1 << 1)) { | ||
385 | rdev->pm.req_vblank |= (1 << 1); | ||
386 | drm_vblank_get(rdev->ddev, 1); | ||
387 | } | ||
388 | radeon_pm_set_clocks_locked(rdev); | ||
389 | if (rdev->pm.req_vblank & (1 << 0)) { | ||
390 | rdev->pm.req_vblank &= ~(1 << 0); | ||
391 | drm_vblank_put(rdev->ddev, 0); | ||
392 | } | ||
393 | if (rdev->pm.req_vblank & (1 << 1)) { | ||
394 | rdev->pm.req_vblank &= ~(1 << 1); | ||
395 | drm_vblank_put(rdev->ddev, 1); | ||
396 | } | ||
397 | |||
398 | mutex_unlock(&rdev->cp.mutex); | ||
399 | } | ||
400 | |||
401 | static void radeon_pm_idle_work_handler(struct work_struct *work) | ||
402 | { | ||
403 | struct radeon_device *rdev; | ||
404 | rdev = container_of(work, struct radeon_device, | ||
405 | pm.idle_work.work); | ||
406 | |||
407 | mutex_lock(&rdev->pm.mutex); | ||
408 | if (rdev->pm.state == PM_STATE_ACTIVE) { | ||
409 | unsigned long irq_flags; | ||
410 | int not_processed = 0; | ||
411 | |||
412 | read_lock_irqsave(&rdev->fence_drv.lock, irq_flags); | ||
413 | if (!list_empty(&rdev->fence_drv.emited)) { | ||
414 | struct list_head *ptr; | ||
415 | list_for_each(ptr, &rdev->fence_drv.emited) { | ||
416 | /* count up to 3, that's enought info */ | ||
417 | if (++not_processed >= 3) | ||
418 | break; | ||
419 | } | ||
420 | } | ||
421 | read_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | ||
422 | |||
423 | if (not_processed >= 3) { /* should upclock */ | ||
424 | if (rdev->pm.planned_action == PM_ACTION_DOWNCLOCK) { | ||
425 | rdev->pm.planned_action = PM_ACTION_NONE; | ||
426 | } else if (rdev->pm.planned_action == PM_ACTION_NONE && | ||
427 | rdev->pm.downclocked) { | ||
428 | rdev->pm.planned_action = | ||
429 | PM_ACTION_UPCLOCK; | ||
430 | rdev->pm.action_timeout = jiffies + | ||
431 | msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); | ||
432 | } | ||
433 | } else if (not_processed == 0) { /* should downclock */ | ||
434 | if (rdev->pm.planned_action == PM_ACTION_UPCLOCK) { | ||
435 | rdev->pm.planned_action = PM_ACTION_NONE; | ||
436 | } else if (rdev->pm.planned_action == PM_ACTION_NONE && | ||
437 | !rdev->pm.downclocked) { | ||
438 | rdev->pm.planned_action = | ||
439 | PM_ACTION_DOWNCLOCK; | ||
440 | rdev->pm.action_timeout = jiffies + | ||
441 | msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); | ||
442 | } | ||
443 | } | ||
444 | |||
445 | if (rdev->pm.planned_action != PM_ACTION_NONE && | ||
446 | jiffies > rdev->pm.action_timeout) { | ||
447 | radeon_pm_set_clocks(rdev); | ||
448 | } | ||
449 | } | ||
450 | mutex_unlock(&rdev->pm.mutex); | ||
451 | |||
452 | queue_delayed_work(rdev->wq, &rdev->pm.idle_work, | ||
453 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | ||
454 | } | ||
455 | |||
36 | /* | 456 | /* |
37 | * Debugfs info | 457 | * Debugfs info |
38 | */ | 458 | */ |
@@ -44,8 +464,14 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) | |||
44 | struct drm_device *dev = node->minor->dev; | 464 | struct drm_device *dev = node->minor->dev; |
45 | struct radeon_device *rdev = dev->dev_private; | 465 | struct radeon_device *rdev = dev->dev_private; |
46 | 466 | ||
47 | seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev)); | 467 | seq_printf(m, "state: %s\n", pm_state_names[rdev->pm.state]); |
48 | seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev)); | 468 | seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk); |
469 | seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); | ||
470 | seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk); | ||
471 | if (rdev->asic->get_memory_clock) | ||
472 | seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); | ||
473 | if (rdev->asic->get_pcie_lanes) | ||
474 | seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev)); | ||
49 | 475 | ||
50 | return 0; | 476 | return 0; |
51 | } | 477 | } |
@@ -55,7 +481,7 @@ static struct drm_info_list radeon_pm_info_list[] = { | |||
55 | }; | 481 | }; |
56 | #endif | 482 | #endif |
57 | 483 | ||
58 | int radeon_debugfs_pm_init(struct radeon_device *rdev) | 484 | static int radeon_debugfs_pm_init(struct radeon_device *rdev) |
59 | { | 485 | { |
60 | #if defined(CONFIG_DEBUG_FS) | 486 | #if defined(CONFIG_DEBUG_FS) |
61 | return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list)); | 487 | return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list)); |