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