gdb - Local mods (compile)
[dragonfly.git] / sys / dev / drm / radeon / radeon_acpi.c
1 /*
2  * Copyright 2012 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * $FreeBSD: head/sys/dev/drm2/radeon/radeon_acpi.c 254885 2013-08-25 19:37:15Z dumbbell $
23  */
24
25 #include <drm/drmP.h>
26 #include <drm/drm_crtc_helper.h>
27 #include "radeon.h"
28 #include "radeon_acpi.h"
29 #include "atom.h"
30
31 #define ACPI_AC_CLASS           "ac_adapter"
32
33 struct atif_verify_interface {
34         u16 size;               /* structure size in bytes (includes size field) */
35         u16 version;            /* version */
36         u32 notification_mask;  /* supported notifications mask */
37         u32 function_bits;      /* supported functions bit vector */
38 } __packed;
39
40 struct atif_system_params {
41         u16 size;               /* structure size in bytes (includes size field) */
42         u32 valid_mask;         /* valid flags mask */
43         u32 flags;              /* flags */
44         u8 command_code;        /* notify command code */
45 } __packed;
46
47 struct atif_sbios_requests {
48         u16 size;               /* structure size in bytes (includes size field) */
49         u32 pending;            /* pending sbios requests */
50         u8 panel_exp_mode;      /* panel expansion mode */
51         u8 thermal_gfx;         /* thermal state: target gfx controller */
52         u8 thermal_state;       /* thermal state: state id (0: exit state, non-0: state) */
53         u8 forced_power_gfx;    /* forced power state: target gfx controller */
54         u8 forced_power_state;  /* forced power state: state id */
55         u8 system_power_src;    /* system power source */
56         u8 backlight_level;     /* panel backlight level (0-255) */
57 } __packed;
58
59 #define ATIF_NOTIFY_MASK        0x3
60 #define ATIF_NOTIFY_NONE        0
61 #define ATIF_NOTIFY_81          1
62 #define ATIF_NOTIFY_N           2
63
64 struct atcs_verify_interface {
65         u16 size;               /* structure size in bytes (includes size field) */
66         u16 version;            /* version */
67         u32 function_bits;      /* supported functions bit vector */
68 } __packed;
69
70 #define ATCS_VALID_FLAGS_MASK   0x3
71
72 struct atcs_pref_req_input {
73         u16 size;               /* structure size in bytes (includes size field) */
74         u16 client_id;          /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
75         u16 valid_flags_mask;   /* valid flags mask */
76         u16 flags;              /* flags */
77         u8 req_type;            /* request type */
78         u8 perf_req;            /* performance request */
79 } __packed;
80
81 struct atcs_pref_req_output {
82         u16 size;               /* structure size in bytes (includes size field) */
83         u8 ret_val;             /* return value */
84 } __packed;
85
86 /* Call the ATIF method
87  */
88 /**
89  * radeon_atif_call - call an ATIF method
90  *
91  * @handle: acpi handle
92  * @function: the ATIF function to execute
93  * @params: ATIF function params
94  *
95  * Executes the requested ATIF function (all asics).
96  * Returns a pointer to the acpi output buffer.
97  */
98 static ACPI_OBJECT *radeon_atif_call(ACPI_HANDLE handle, int function,
99                 ACPI_BUFFER *params)
100 {
101         ACPI_STATUS status;
102         ACPI_OBJECT atif_arg_elements[2];
103         ACPI_OBJECT_LIST atif_arg;
104         ACPI_BUFFER buffer = { ACPI_ALLOCATE_BUFFER, NULL };
105
106         atif_arg.Count = 2;
107         atif_arg.Pointer = &atif_arg_elements[0];
108
109         atif_arg_elements[0].Type = ACPI_TYPE_INTEGER;
110         atif_arg_elements[0].Integer.Value = function;
111
112         if (params) {
113                 atif_arg_elements[1].Type = ACPI_TYPE_BUFFER;
114                 atif_arg_elements[1].Buffer.Length = params->Length;
115                 atif_arg_elements[1].Buffer.Pointer = params->Pointer;
116         } else {
117                 /* We need a second fake parameter */
118                 atif_arg_elements[1].Type = ACPI_TYPE_INTEGER;
119                 atif_arg_elements[1].Integer.Value = 0;
120         }
121
122         status = AcpiEvaluateObject(handle, "ATIF", &atif_arg, &buffer);
123
124         /* Fail only if calling the method fails and ATIF is supported */
125         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
126                 DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
127                                  AcpiFormatException(status));
128                 AcpiOsFree(buffer.Pointer);
129                 return NULL;
130         }
131
132         return buffer.Pointer;
133 }
134
135 /**
136  * radeon_atif_parse_notification - parse supported notifications
137  *
138  * @n: supported notifications struct
139  * @mask: supported notifications mask from ATIF
140  *
141  * Use the supported notifications mask from ATIF function
142  * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications
143  * are supported (all asics).
144  */
145 static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask)
146 {
147         n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED;
148         n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED;
149         n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
150         n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
151         n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
152         n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED;
153         n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED;
154         n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
155         n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
156 }
157
158 /**
159  * radeon_atif_parse_functions - parse supported functions
160  *
161  * @f: supported functions struct
162  * @mask: supported functions mask from ATIF
163  *
164  * Use the supported functions mask from ATIF function
165  * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions
166  * are supported (all asics).
167  */
168 static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask)
169 {
170         f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
171         f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
172         f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED;
173         f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED;
174         f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED;
175         f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED;
176         f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED;
177         f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED;
178         f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
179         f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED;
180 }
181
182 /**
183  * radeon_atif_verify_interface - verify ATIF
184  *
185  * @handle: acpi handle
186  * @atif: radeon atif struct
187  *
188  * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function
189  * to initialize ATIF and determine what features are supported
190  * (all asics).
191  * returns 0 on success, error on failure.
192  */
193 static int radeon_atif_verify_interface(ACPI_HANDLE handle,
194                 struct radeon_atif *atif)
195 {
196         ACPI_OBJECT *info;
197         struct atif_verify_interface output;
198         size_t size;
199         int err = 0;
200
201         info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
202         if (!info)
203                 return -EIO;
204
205         memset(&output, 0, sizeof(output));
206
207         size = *(u16 *) info->Buffer.Pointer;
208         if (size < 12) {
209                 DRM_INFO("ATIF buffer is too small: %zu\n", size);
210                 err = -EINVAL;
211                 goto out;
212         }
213         size = min(sizeof(output), size);
214
215         memcpy(&output, info->Buffer.Pointer, size);
216
217         /* TODO: check version? */
218         DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
219
220         radeon_atif_parse_notification(&atif->notifications, output.notification_mask);
221         radeon_atif_parse_functions(&atif->functions, output.function_bits);
222
223 out:
224         AcpiOsFree(info);
225         return err;
226 }
227
228 /**
229  * radeon_atif_get_notification_params - determine notify configuration
230  *
231  * @handle: acpi handle
232  * @n: atif notification configuration struct
233  *
234  * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function
235  * to determine if a notifier is used and if so which one
236  * (all asics).  This is either Notify(VGA, 0x81) or Notify(VGA, n)
237  * where n is specified in the result if a notifier is used.
238  * Returns 0 on success, error on failure.
239  */
240 static int radeon_atif_get_notification_params(ACPI_HANDLE handle,
241                 struct radeon_atif_notification_cfg *n)
242 {
243         ACPI_OBJECT *info;
244         struct atif_system_params params;
245         size_t size;
246         int err = 0;
247
248         info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL);
249         if (!info) {
250                 err = -EIO;
251                 goto out;
252         }
253
254         size = *(u16 *) info->Buffer.Pointer;
255         if (size < 10) {
256                 err = -EINVAL;
257                 goto out;
258         }
259
260         memset(&params, 0, sizeof(params));
261         size = min(sizeof(params), size);
262         memcpy(&params, info->Buffer.Pointer, size);
263
264         DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
265                         params.flags, params.valid_mask);
266         params.flags = params.flags & params.valid_mask;
267
268         if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
269                 n->enabled = false;
270                 n->command_code = 0;
271         } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
272                 n->enabled = true;
273                 n->command_code = 0x81;
274         } else {
275                 if (size < 11) {
276                         err = -EINVAL;
277                         goto out;
278                 }
279                 n->enabled = true;
280                 n->command_code = params.command_code;
281         }
282
283 out:
284         DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
285                         (n->enabled ? "enabled" : "disabled"),
286                         n->command_code);
287         AcpiOsFree(info);
288         return err;
289 }
290
291 /**
292  * radeon_atif_get_sbios_requests - get requested sbios event
293  *
294  * @handle: acpi handle
295  * @req: atif sbios request struct
296  *
297  * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function
298  * to determine what requests the sbios is making to the driver
299  * (all asics).
300  * Returns 0 on success, error on failure.
301  */
302 static int radeon_atif_get_sbios_requests(ACPI_HANDLE handle,
303                 struct atif_sbios_requests *req)
304 {
305         ACPI_OBJECT *info;
306         size_t size;
307         int count = 0;
308
309         info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL);
310         if (!info)
311                 return -EIO;
312
313         size = *(u16 *)info->Buffer.Pointer;
314         if (size < 0xd) {
315                 count = -EINVAL;
316                 goto out;
317         }
318         memset(req, 0, sizeof(*req));
319
320         size = min(sizeof(*req), size);
321         memcpy(req, info->Buffer.Pointer, size);
322         DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
323
324         count = hweight32(req->pending);
325
326 out:
327         AcpiOsFree(info);
328         return count;
329 }
330
331 /**
332  * radeon_atif_handler - handle ATIF notify requests
333  *
334  * @rdev: radeon_device pointer
335  * @event: atif sbios request struct
336  *
337  * Checks the acpi event and if it matches an atif event,
338  * handles it.
339  * Returns NOTIFY code
340  */
341 void radeon_atif_handler(struct radeon_device *rdev,
342     UINT32 type)
343 {
344         struct radeon_atif *atif = &rdev->atif;
345         struct atif_sbios_requests req;
346         ACPI_HANDLE handle;
347         int count;
348
349         DRM_DEBUG_DRIVER("event, type = %#x\n",
350                         type);
351
352         if (!atif->notification_cfg.enabled ||
353                         type != atif->notification_cfg.command_code)
354                 /* Not our event */
355                 return;
356
357         /* Check pending SBIOS requests */
358         handle = rdev->acpi.handle;
359         count = radeon_atif_get_sbios_requests(handle, &req);
360
361         if (count <= 0)
362                 return;
363
364         DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
365
366         if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
367                 struct radeon_encoder *enc = atif->encoder_for_bl;
368
369                 if (enc) {
370                         DRM_DEBUG_DRIVER("Changing brightness to %d\n",
371                                         req.backlight_level);
372
373                         radeon_set_backlight_level(rdev, enc, req.backlight_level);
374
375 #ifdef DUMBBELL_WIP
376                         if (rdev->is_atom_bios) {
377                                 struct radeon_encoder_atom_dig *dig = enc->enc_priv;
378                                 backlight_force_update(dig->bl_dev,
379                                                        BACKLIGHT_UPDATE_HOTKEY);
380                         } else {
381                                 struct radeon_encoder_lvds *dig = enc->enc_priv;
382                                 backlight_force_update(dig->bl_dev,
383                                                        BACKLIGHT_UPDATE_HOTKEY);
384                         }
385 #endif /* DUMBBELL_WIP */
386                 }
387         }
388         /* TODO: check other events */
389
390         /* We've handled the event, stop the notifier chain. The ACPI interface
391          * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
392          * userspace if the event was generated only to signal a SBIOS
393          * request.
394          */
395 }
396
397 /* Call the ATCS method
398  */
399 /**
400  * radeon_atcs_call - call an ATCS method
401  *
402  * @handle: acpi handle
403  * @function: the ATCS function to execute
404  * @params: ATCS function params
405  *
406  * Executes the requested ATCS function (all asics).
407  * Returns a pointer to the acpi output buffer.
408  */
409 static union acpi_object *radeon_atcs_call(ACPI_HANDLE handle, int function,
410                                            ACPI_BUFFER *params)
411 {
412         ACPI_STATUS status;
413         ACPI_OBJECT atcs_arg_elements[2];
414         ACPI_OBJECT_LIST atcs_arg;
415         ACPI_BUFFER buffer = { ACPI_ALLOCATE_BUFFER, NULL };
416
417         atcs_arg.Count = 2;
418         atcs_arg.Pointer = &atcs_arg_elements[0];
419
420         atcs_arg_elements[0].Type = ACPI_TYPE_INTEGER;
421         atcs_arg_elements[0].Integer.Value = function;
422
423         if (params) {
424                 atcs_arg_elements[1].Type = ACPI_TYPE_BUFFER;
425                 atcs_arg_elements[1].Buffer.Length = params->Length;
426                 atcs_arg_elements[1].Buffer.Pointer = params->Pointer;
427         } else {
428                 /* We need a second fake parameter */
429                 atcs_arg_elements[1].Type = ACPI_TYPE_INTEGER;
430                 atcs_arg_elements[1].Integer.Value = 0;
431         }
432
433         status = AcpiEvaluateObject(handle, "ATCS", &atcs_arg, &buffer);
434
435         /* Fail only if calling the method fails and ATIF is supported */
436         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
437                 DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
438                                  AcpiFormatException(status));
439                 AcpiOsFree(buffer.Pointer);
440                 return NULL;
441         }
442
443         return buffer.Pointer;
444 }
445
446 /**
447  * radeon_atcs_parse_functions - parse supported functions
448  *
449  * @f: supported functions struct
450  * @mask: supported functions mask from ATCS
451  *
452  * Use the supported functions mask from ATCS function
453  * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
454  * are supported (all asics).
455  */
456 static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask)
457 {
458         f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
459         f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
460         f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
461         f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
462 }
463
464 /**
465  * radeon_atcs_verify_interface - verify ATCS
466  *
467  * @handle: acpi handle
468  * @atcs: radeon atcs struct
469  *
470  * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
471  * to initialize ATCS and determine what features are supported
472  * (all asics).
473  * returns 0 on success, error on failure.
474  */
475 static int radeon_atcs_verify_interface(ACPI_HANDLE handle,
476                                         struct radeon_atcs *atcs)
477 {
478         ACPI_OBJECT *info;
479         struct atcs_verify_interface output;
480         size_t size;
481         int err = 0;
482
483         info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
484         if (!info)
485                 return -EIO;
486
487         memset(&output, 0, sizeof(output));
488
489         size = *(u16 *) info->Buffer.Pointer;
490         if (size < 8) {
491                 DRM_INFO("ATCS buffer is too small: %zu\n", size);
492                 err = -EINVAL;
493                 goto out;
494         }
495         size = min(sizeof(output), size);
496
497         memcpy(&output, info->Buffer.Pointer, size);
498
499         /* TODO: check version? */
500         DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
501
502         radeon_atcs_parse_functions(&atcs->functions, output.function_bits);
503
504 out:
505         AcpiOsFree(info);
506         return err;
507 }
508
509 /**
510  * radeon_acpi_is_pcie_performance_request_supported
511  *
512  * @rdev: radeon_device pointer
513  *
514  * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods
515  * are supported (all asics).
516  * returns true if supported, false if not.
517  */
518 bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev)
519 {
520         struct radeon_atcs *atcs = &rdev->atcs;
521
522         if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)
523                 return true;
524
525         return false;
526 }
527
528 /**
529  * radeon_acpi_pcie_notify_device_ready
530  *
531  * @rdev: radeon_device pointer
532  *
533  * Executes the PCIE_DEVICE_READY_NOTIFICATION method
534  * (all asics).
535  * returns 0 on success, error on failure.
536  */
537 int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev)
538 {
539 #ifdef MN_TODO
540         acpi_handle handle;
541         union acpi_object *info;
542         struct radeon_atcs *atcs = &rdev->atcs;
543
544         /* Get the device handle */
545         handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
546         if (!handle)
547                 return -EINVAL;
548
549         if (!atcs->functions.pcie_dev_rdy)
550                 return -EINVAL;
551
552         info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
553         if (!info)
554                 return -EIO;
555
556         kfree(info);
557
558         return 0;
559 #else
560         return -EINVAL;
561 #endif
562 }
563
564 /**
565  * radeon_acpi_pcie_performance_request
566  *
567  * @rdev: radeon_device pointer
568  * @perf_req: requested perf level (pcie gen speed)
569  * @advertise: set advertise caps flag if set
570  *
571  * Executes the PCIE_PERFORMANCE_REQUEST method to
572  * change the pcie gen speed (all asics).
573  * returns 0 on success, error on failure.
574  */
575 int radeon_acpi_pcie_performance_request(struct radeon_device *rdev,
576                                          u8 perf_req, bool advertise)
577 {
578 #ifdef MN_TODO
579         acpi_handle handle;
580         union acpi_object *info;
581         struct radeon_atcs *atcs = &rdev->atcs;
582         struct atcs_pref_req_input atcs_input;
583         struct atcs_pref_req_output atcs_output;
584         struct acpi_buffer params;
585         size_t size;
586         u32 retry = 3;
587
588         /* Get the device handle */
589         handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
590         if (!handle)
591                 return -EINVAL;
592
593         if (!atcs->functions.pcie_perf_req)
594                 return -EINVAL;
595
596         atcs_input.size = sizeof(struct atcs_pref_req_input);
597         /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
598         atcs_input.client_id = rdev->pdev->devfn | (rdev->pdev->bus->number << 8);
599         atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
600         atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
601         if (advertise)
602                 atcs_input.flags |= ATCS_ADVERTISE_CAPS;
603         atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
604         atcs_input.perf_req = perf_req;
605
606         params.length = sizeof(struct atcs_pref_req_input);
607         params.pointer = &atcs_input;
608
609         while (retry--) {
610                 info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, &params);
611                 if (!info)
612                         return -EIO;
613
614                 memset(&atcs_output, 0, sizeof(atcs_output));
615
616                 size = *(u16 *) info->buffer.pointer;
617                 if (size < 3) {
618                         DRM_INFO("ATCS buffer is too small: %zu\n", size);
619                         kfree(info);
620                         return -EINVAL;
621                 }
622                 size = min(sizeof(atcs_output), size);
623
624                 memcpy(&atcs_output, info->buffer.pointer, size);
625
626                 kfree(info);
627
628                 switch (atcs_output.ret_val) {
629                 case ATCS_REQUEST_REFUSED:
630                 default:
631                         return -EINVAL;
632                 case ATCS_REQUEST_COMPLETE:
633                         return 0;
634                 case ATCS_REQUEST_IN_PROGRESS:
635                         udelay(10);
636                         break;
637                 }
638         }
639
640         return 0;
641 #else
642         return -EINVAL;
643 #endif
644 }
645
646 /**
647  * radeon_acpi_event - handle notify events
648  *
649  * @nb: notifier block
650  * @val: val
651  * @data: acpi event
652  *
653  * Calls relevant radeon functions in response to various
654  * acpi events.
655  * Returns NOTIFY code
656  */
657 static void radeon_acpi_event(ACPI_HANDLE handle, UINT32 type,
658     void *context)
659 {
660         struct radeon_device *rdev = (struct radeon_device *)context;
661
662 #ifdef DUMBBELL_WIP
663         if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
664                 if (power_supply_is_system_supplied() > 0)
665                         DRM_DEBUG_DRIVER("pm: AC\n");
666                 else
667                         DRM_DEBUG_DRIVER("pm: DC\n");
668
669                 radeon_pm_acpi_event_handler(rdev);
670         }
671 #endif /* DUMBBELL_WIP */
672
673         /* Check for pending SBIOS requests */
674         radeon_atif_handler(rdev, type);
675 }
676
677 /* Call all ACPI methods here */
678 /**
679  * radeon_acpi_init - init driver acpi support
680  *
681  * @rdev: radeon_device pointer
682  *
683  * Verifies the AMD ACPI interfaces and registers with the acpi
684  * notifier chain (all asics).
685  * Returns 0 on success, error on failure.
686  */
687 int radeon_acpi_init(struct radeon_device *rdev)
688 {
689         ACPI_HANDLE handle;
690         struct radeon_atif *atif = &rdev->atif;
691         struct radeon_atcs *atcs = &rdev->atcs;
692         int ret;
693
694         /* Get the device handle */
695         handle = acpi_get_handle(rdev->dev);
696
697         /* No need to proceed if we're sure that ATIF is not supported */
698         if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
699                 return 0;
700
701         /* Call the ATCS method */
702         ret = radeon_atcs_verify_interface(handle, atcs);
703         if (ret) {
704                 DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
705         }
706
707         /* Call the ATIF method */
708         ret = radeon_atif_verify_interface(handle, atif);
709         if (ret) {
710                 DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
711                 goto out;
712         }
713
714         if (atif->notifications.brightness_change) {
715                 struct drm_encoder *tmp;
716                 struct radeon_encoder *target = NULL;
717
718                 /* Find the encoder controlling the brightness */
719                 list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list,
720                                 head) {
721                         struct radeon_encoder *enc = to_radeon_encoder(tmp);
722
723                         if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
724                             enc->enc_priv) {
725                                 if (rdev->is_atom_bios) {
726                                         struct radeon_encoder_atom_dig *dig = enc->enc_priv;
727                                         if (dig->bl_dev) {
728                                                 target = enc;
729                                                 break;
730                                         }
731                                 } else {
732                                         struct radeon_encoder_lvds *dig = enc->enc_priv;
733                                         if (dig->bl_dev) {
734                                                 target = enc;
735                                                 break;
736                                         }
737                                 }
738                         }
739                 }
740
741                 atif->encoder_for_bl = target;
742                 if (!target) {
743                         /* Brightness change notification is enabled, but we
744                          * didn't find a backlight controller, this should
745                          * never happen.
746                          */
747                         DRM_ERROR("Cannot find a backlight controller\n");
748                 }
749         }
750
751         if (atif->functions.sbios_requests && !atif->functions.system_params) {
752                 /* XXX check this workraround, if sbios request function is
753                  * present we have to see how it's configured in the system
754                  * params
755                  */
756                 atif->functions.system_params = true;
757         }
758
759         if (atif->functions.system_params) {
760                 ret = radeon_atif_get_notification_params(handle,
761                                 &atif->notification_cfg);
762                 if (ret) {
763                         DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
764                                         ret);
765                         /* Disable notification */
766                         atif->notification_cfg.enabled = false;
767                 }
768         }
769
770 out:
771         rdev->acpi.handle = handle;
772         rdev->acpi.notifier_call = radeon_acpi_event;
773         AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
774             rdev->acpi.notifier_call, rdev);
775
776         return ret;
777 }
778
779 /**
780  * radeon_acpi_fini - tear down driver acpi support
781  *
782  * @rdev: radeon_device pointer
783  *
784  * Unregisters with the acpi notifier chain (all asics).
785  */
786 void radeon_acpi_fini(struct radeon_device *rdev)
787 {
788         AcpiRemoveNotifyHandler(rdev->acpi.handle, ACPI_DEVICE_NOTIFY,
789             rdev->acpi.notifier_call);
790 }