amdgpu_acpi.c revision 1.1.1.2 1 /* $NetBSD: amdgpu_acpi.c,v 1.1.1.2 2021/12/18 20:11:04 riastradh 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.1.1.2 2021/12/18 20:11:04 riastradh 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 <linux/pm_runtime.h>
34 #include <acpi/video.h>
35
36 #include <drm/drm_crtc_helper.h>
37 #include "amdgpu.h"
38 #include "amdgpu_pm.h"
39 #include "amdgpu_display.h"
40 #include "amd_acpi.h"
41 #include "atom.h"
42
43 struct amdgpu_atif_notification_cfg {
44 bool enabled;
45 int command_code;
46 };
47
48 struct amdgpu_atif_notifications {
49 bool thermal_state;
50 bool forced_power_state;
51 bool system_power_state;
52 bool brightness_change;
53 bool dgpu_display_event;
54 bool gpu_package_power_limit;
55 };
56
57 struct amdgpu_atif_functions {
58 bool system_params;
59 bool sbios_requests;
60 bool temperature_change;
61 bool query_backlight_transfer_characteristics;
62 bool ready_to_undock;
63 bool external_gpu_information;
64 };
65
66 struct amdgpu_atif {
67 acpi_handle handle;
68
69 struct amdgpu_atif_notifications notifications;
70 struct amdgpu_atif_functions functions;
71 struct amdgpu_atif_notification_cfg notification_cfg;
72 struct amdgpu_encoder *encoder_for_bl;
73 struct amdgpu_dm_backlight_caps backlight_caps;
74 };
75
76 /* Call the ATIF method
77 */
78 /**
79 * amdgpu_atif_call - call an ATIF method
80 *
81 * @handle: acpi handle
82 * @function: the ATIF function to execute
83 * @params: ATIF function params
84 *
85 * Executes the requested ATIF function (all asics).
86 * Returns a pointer to the acpi output buffer.
87 */
88 static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
89 int function,
90 struct acpi_buffer *params)
91 {
92 acpi_status status;
93 union acpi_object atif_arg_elements[2];
94 struct acpi_object_list atif_arg;
95 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
96
97 atif_arg.count = 2;
98 atif_arg.pointer = &atif_arg_elements[0];
99
100 atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
101 atif_arg_elements[0].integer.value = function;
102
103 if (params) {
104 atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
105 atif_arg_elements[1].buffer.length = params->length;
106 atif_arg_elements[1].buffer.pointer = params->pointer;
107 } else {
108 /* We need a second fake parameter */
109 atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
110 atif_arg_elements[1].integer.value = 0;
111 }
112
113 status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
114 &buffer);
115
116 /* Fail only if calling the method fails and ATIF is supported */
117 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
118 DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
119 acpi_format_exception(status));
120 kfree(buffer.pointer);
121 return NULL;
122 }
123
124 return buffer.pointer;
125 }
126
127 /**
128 * amdgpu_atif_parse_notification - parse supported notifications
129 *
130 * @n: supported notifications struct
131 * @mask: supported notifications mask from ATIF
132 *
133 * Use the supported notifications mask from ATIF function
134 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications
135 * are supported (all asics).
136 */
137 static void amdgpu_atif_parse_notification(struct amdgpu_atif_notifications *n, u32 mask)
138 {
139 n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
140 n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
141 n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
142 n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
143 n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
144 n->gpu_package_power_limit = mask & ATIF_GPU_PACKAGE_POWER_LIMIT_REQUEST_SUPPORTED;
145 }
146
147 /**
148 * amdgpu_atif_parse_functions - parse supported functions
149 *
150 * @f: supported functions struct
151 * @mask: supported functions mask from ATIF
152 *
153 * Use the supported functions mask from ATIF function
154 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions
155 * are supported (all asics).
156 */
157 static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mask)
158 {
159 f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
160 f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
161 f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
162 f->query_backlight_transfer_characteristics =
163 mask & ATIF_QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS_SUPPORTED;
164 f->ready_to_undock = mask & ATIF_READY_TO_UNDOCK_NOTIFICATION_SUPPORTED;
165 f->external_gpu_information = mask & ATIF_GET_EXTERNAL_GPU_INFORMATION_SUPPORTED;
166 }
167
168 /**
169 * amdgpu_atif_verify_interface - verify ATIF
170 *
171 * @handle: acpi handle
172 * @atif: amdgpu atif struct
173 *
174 * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function
175 * to initialize ATIF and determine what features are supported
176 * (all asics).
177 * returns 0 on success, error on failure.
178 */
179 static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif)
180 {
181 union acpi_object *info;
182 struct atif_verify_interface output;
183 size_t size;
184 int err = 0;
185
186 info = amdgpu_atif_call(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
187 if (!info)
188 return -EIO;
189
190 memset(&output, 0, sizeof(output));
191
192 size = *(u16 *) info->buffer.pointer;
193 if (size < 12) {
194 DRM_INFO("ATIF buffer is too small: %zu\n", size);
195 err = -EINVAL;
196 goto out;
197 }
198 size = min(sizeof(output), size);
199
200 memcpy(&output, info->buffer.pointer, size);
201
202 /* TODO: check version? */
203 DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
204
205 amdgpu_atif_parse_notification(&atif->notifications, output.notification_mask);
206 amdgpu_atif_parse_functions(&atif->functions, output.function_bits);
207
208 out:
209 kfree(info);
210 return err;
211 }
212
213 static acpi_handle amdgpu_atif_probe_handle(acpi_handle dhandle)
214 {
215 acpi_handle handle = NULL;
216 char acpi_method_name[255] = { 0 };
217 struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name };
218 acpi_status status;
219
220 /* For PX/HG systems, ATIF and ATPX are in the iGPU's namespace, on dGPU only
221 * systems, ATIF is in the dGPU's namespace.
222 */
223 status = acpi_get_handle(dhandle, "ATIF", &handle);
224 if (ACPI_SUCCESS(status))
225 goto out;
226
227 if (amdgpu_has_atpx()) {
228 status = acpi_get_handle(amdgpu_atpx_get_dhandle(), "ATIF",
229 &handle);
230 if (ACPI_SUCCESS(status))
231 goto out;
232 }
233
234 DRM_DEBUG_DRIVER("No ATIF handle found\n");
235 return NULL;
236 out:
237 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
238 DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name);
239 return handle;
240 }
241
242 /**
243 * amdgpu_atif_get_notification_params - determine notify configuration
244 *
245 * @handle: acpi handle
246 * @n: atif notification configuration struct
247 *
248 * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function
249 * to determine if a notifier is used and if so which one
250 * (all asics). This is either Notify(VGA, 0x81) or Notify(VGA, n)
251 * where n is specified in the result if a notifier is used.
252 * Returns 0 on success, error on failure.
253 */
254 static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)
255 {
256 union acpi_object *info;
257 struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg;
258 struct atif_system_params params;
259 size_t size;
260 int err = 0;
261
262 info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS,
263 NULL);
264 if (!info) {
265 err = -EIO;
266 goto out;
267 }
268
269 size = *(u16 *) info->buffer.pointer;
270 if (size < 10) {
271 err = -EINVAL;
272 goto out;
273 }
274
275 memset(¶ms, 0, sizeof(params));
276 size = min(sizeof(params), size);
277 memcpy(¶ms, info->buffer.pointer, size);
278
279 DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
280 params.flags, params.valid_mask);
281 params.flags = params.flags & params.valid_mask;
282
283 if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
284 n->enabled = false;
285 n->command_code = 0;
286 } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
287 n->enabled = true;
288 n->command_code = 0x81;
289 } else {
290 if (size < 11) {
291 err = -EINVAL;
292 goto out;
293 }
294 n->enabled = true;
295 n->command_code = params.command_code;
296 }
297
298 out:
299 DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
300 (n->enabled ? "enabled" : "disabled"),
301 n->command_code);
302 kfree(info);
303 return err;
304 }
305
306 /**
307 * amdgpu_atif_query_backlight_caps - get min and max backlight input signal
308 *
309 * @handle: acpi handle
310 *
311 * Execute the QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS ATIF function
312 * to determine the acceptable range of backlight values
313 *
314 * Backlight_caps.caps_valid will be set to true if the query is successful
315 *
316 * The input signals are in range 0-255
317 *
318 * This function assumes the display with backlight is the first LCD
319 *
320 * Returns 0 on success, error on failure.
321 */
322 static int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif)
323 {
324 union acpi_object *info;
325 struct atif_qbtc_output characteristics;
326 struct atif_qbtc_arguments arguments;
327 struct acpi_buffer params;
328 size_t size;
329 int err = 0;
330
331 arguments.size = sizeof(arguments);
332 arguments.requested_display = ATIF_QBTC_REQUEST_LCD1;
333
334 params.length = sizeof(arguments);
335 params.pointer = (void *)&arguments;
336
337 info = amdgpu_atif_call(atif,
338 ATIF_FUNCTION_QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS,
339 ¶ms);
340 if (!info) {
341 err = -EIO;
342 goto out;
343 }
344
345 size = *(u16 *) info->buffer.pointer;
346 if (size < 10) {
347 err = -EINVAL;
348 goto out;
349 }
350
351 memset(&characteristics, 0, sizeof(characteristics));
352 size = min(sizeof(characteristics), size);
353 memcpy(&characteristics, info->buffer.pointer, size);
354
355 atif->backlight_caps.caps_valid = true;
356 atif->backlight_caps.min_input_signal =
357 characteristics.min_input_signal;
358 atif->backlight_caps.max_input_signal =
359 characteristics.max_input_signal;
360 out:
361 kfree(info);
362 return err;
363 }
364
365 /**
366 * amdgpu_atif_get_sbios_requests - get requested sbios event
367 *
368 * @handle: acpi handle
369 * @req: atif sbios request struct
370 *
371 * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function
372 * to determine what requests the sbios is making to the driver
373 * (all asics).
374 * Returns 0 on success, error on failure.
375 */
376 static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif,
377 struct atif_sbios_requests *req)
378 {
379 union acpi_object *info;
380 size_t size;
381 int count = 0;
382
383 info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS,
384 NULL);
385 if (!info)
386 return -EIO;
387
388 size = *(u16 *)info->buffer.pointer;
389 if (size < 0xd) {
390 count = -EINVAL;
391 goto out;
392 }
393 memset(req, 0, sizeof(*req));
394
395 size = min(sizeof(*req), size);
396 memcpy(req, info->buffer.pointer, size);
397 DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
398
399 count = hweight32(req->pending);
400
401 out:
402 kfree(info);
403 return count;
404 }
405
406 /**
407 * amdgpu_atif_handler - handle ATIF notify requests
408 *
409 * @adev: amdgpu_device pointer
410 * @event: atif sbios request struct
411 *
412 * Checks the acpi event and if it matches an atif event,
413 * handles it.
414 *
415 * Returns:
416 * NOTIFY_BAD or NOTIFY_DONE, depending on the event.
417 */
418 static int amdgpu_atif_handler(struct amdgpu_device *adev,
419 struct acpi_bus_event *event)
420 {
421 struct amdgpu_atif *atif = adev->atif;
422 int count;
423
424 DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
425 event->device_class, event->type);
426
427 if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
428 return NOTIFY_DONE;
429
430 /* Is this actually our event? */
431 if (!atif ||
432 !atif->notification_cfg.enabled ||
433 event->type != atif->notification_cfg.command_code) {
434 /* These events will generate keypresses otherwise */
435 if (event->type == ACPI_VIDEO_NOTIFY_PROBE)
436 return NOTIFY_BAD;
437 else
438 return NOTIFY_DONE;
439 }
440
441 if (atif->functions.sbios_requests) {
442 struct atif_sbios_requests req;
443
444 /* Check pending SBIOS requests */
445 count = amdgpu_atif_get_sbios_requests(atif, &req);
446
447 if (count <= 0)
448 return NOTIFY_BAD;
449
450 DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
451
452 /* todo: add DC handling */
453 if ((req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) &&
454 !amdgpu_device_has_dc_support(adev)) {
455 struct amdgpu_encoder *enc = atif->encoder_for_bl;
456
457 if (enc) {
458 struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
459
460 DRM_DEBUG_DRIVER("Changing brightness to %d\n",
461 req.backlight_level);
462
463 amdgpu_display_backlight_set_level(adev, enc, req.backlight_level);
464
465 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
466 backlight_force_update(dig->bl_dev,
467 BACKLIGHT_UPDATE_HOTKEY);
468 #endif
469 }
470 }
471 if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
472 if (adev->flags & AMD_IS_PX) {
473 pm_runtime_get_sync(adev->ddev->dev);
474 /* Just fire off a uevent and let userspace tell us what to do */
475 drm_helper_hpd_irq_event(adev->ddev);
476 pm_runtime_mark_last_busy(adev->ddev->dev);
477 pm_runtime_put_autosuspend(adev->ddev->dev);
478 }
479 }
480 /* TODO: check other events */
481 }
482
483 /* We've handled the event, stop the notifier chain. The ACPI interface
484 * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
485 * userspace if the event was generated only to signal a SBIOS
486 * request.
487 */
488 return NOTIFY_BAD;
489 }
490
491 /* Call the ATCS method
492 */
493 /**
494 * amdgpu_atcs_call - call an ATCS method
495 *
496 * @handle: acpi handle
497 * @function: the ATCS function to execute
498 * @params: ATCS function params
499 *
500 * Executes the requested ATCS function (all asics).
501 * Returns a pointer to the acpi output buffer.
502 */
503 static union acpi_object *amdgpu_atcs_call(acpi_handle handle, int function,
504 struct acpi_buffer *params)
505 {
506 acpi_status status;
507 union acpi_object atcs_arg_elements[2];
508 struct acpi_object_list atcs_arg;
509 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
510
511 atcs_arg.count = 2;
512 atcs_arg.pointer = &atcs_arg_elements[0];
513
514 atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;
515 atcs_arg_elements[0].integer.value = function;
516
517 if (params) {
518 atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;
519 atcs_arg_elements[1].buffer.length = params->length;
520 atcs_arg_elements[1].buffer.pointer = params->pointer;
521 } else {
522 /* We need a second fake parameter */
523 atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;
524 atcs_arg_elements[1].integer.value = 0;
525 }
526
527 status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer);
528
529 /* Fail only if calling the method fails and ATIF is supported */
530 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
531 DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
532 acpi_format_exception(status));
533 kfree(buffer.pointer);
534 return NULL;
535 }
536
537 return buffer.pointer;
538 }
539
540 /**
541 * amdgpu_atcs_parse_functions - parse supported functions
542 *
543 * @f: supported functions struct
544 * @mask: supported functions mask from ATCS
545 *
546 * Use the supported functions mask from ATCS function
547 * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
548 * are supported (all asics).
549 */
550 static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mask)
551 {
552 f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
553 f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
554 f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
555 f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
556 }
557
558 /**
559 * amdgpu_atcs_verify_interface - verify ATCS
560 *
561 * @handle: acpi handle
562 * @atcs: amdgpu atcs struct
563 *
564 * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
565 * to initialize ATCS and determine what features are supported
566 * (all asics).
567 * returns 0 on success, error on failure.
568 */
569 static int amdgpu_atcs_verify_interface(acpi_handle handle,
570 struct amdgpu_atcs *atcs)
571 {
572 union acpi_object *info;
573 struct atcs_verify_interface output;
574 size_t size;
575 int err = 0;
576
577 info = amdgpu_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
578 if (!info)
579 return -EIO;
580
581 memset(&output, 0, sizeof(output));
582
583 size = *(u16 *) info->buffer.pointer;
584 if (size < 8) {
585 DRM_INFO("ATCS buffer is too small: %zu\n", size);
586 err = -EINVAL;
587 goto out;
588 }
589 size = min(sizeof(output), size);
590
591 memcpy(&output, info->buffer.pointer, size);
592
593 /* TODO: check version? */
594 DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
595
596 amdgpu_atcs_parse_functions(&atcs->functions, output.function_bits);
597
598 out:
599 kfree(info);
600 return err;
601 }
602
603 /**
604 * amdgpu_acpi_is_pcie_performance_request_supported
605 *
606 * @adev: amdgpu_device pointer
607 *
608 * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods
609 * are supported (all asics).
610 * returns true if supported, false if not.
611 */
612 bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev)
613 {
614 struct amdgpu_atcs *atcs = &adev->atcs;
615
616 if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)
617 return true;
618
619 return false;
620 }
621
622 /**
623 * amdgpu_acpi_pcie_notify_device_ready
624 *
625 * @adev: amdgpu_device pointer
626 *
627 * Executes the PCIE_DEVICE_READY_NOTIFICATION method
628 * (all asics).
629 * returns 0 on success, error on failure.
630 */
631 int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev)
632 {
633 acpi_handle handle;
634 union acpi_object *info;
635 struct amdgpu_atcs *atcs = &adev->atcs;
636
637 /* Get the device handle */
638 handle = ACPI_HANDLE(&adev->pdev->dev);
639 if (!handle)
640 return -EINVAL;
641
642 if (!atcs->functions.pcie_dev_rdy)
643 return -EINVAL;
644
645 info = amdgpu_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
646 if (!info)
647 return -EIO;
648
649 kfree(info);
650
651 return 0;
652 }
653
654 /**
655 * amdgpu_acpi_pcie_performance_request
656 *
657 * @adev: amdgpu_device pointer
658 * @perf_req: requested perf level (pcie gen speed)
659 * @advertise: set advertise caps flag if set
660 *
661 * Executes the PCIE_PERFORMANCE_REQUEST method to
662 * change the pcie gen speed (all asics).
663 * returns 0 on success, error on failure.
664 */
665 int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
666 u8 perf_req, bool advertise)
667 {
668 acpi_handle handle;
669 union acpi_object *info;
670 struct amdgpu_atcs *atcs = &adev->atcs;
671 struct atcs_pref_req_input atcs_input;
672 struct atcs_pref_req_output atcs_output;
673 struct acpi_buffer params;
674 size_t size;
675 u32 retry = 3;
676
677 if (amdgpu_acpi_pcie_notify_device_ready(adev))
678 return -EINVAL;
679
680 /* Get the device handle */
681 handle = ACPI_HANDLE(&adev->pdev->dev);
682 if (!handle)
683 return -EINVAL;
684
685 if (!atcs->functions.pcie_perf_req)
686 return -EINVAL;
687
688 atcs_input.size = sizeof(struct atcs_pref_req_input);
689 /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
690 atcs_input.client_id = adev->pdev->devfn | (adev->pdev->bus->number << 8);
691 atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
692 atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
693 if (advertise)
694 atcs_input.flags |= ATCS_ADVERTISE_CAPS;
695 atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
696 atcs_input.perf_req = perf_req;
697
698 params.length = sizeof(struct atcs_pref_req_input);
699 params.pointer = &atcs_input;
700
701 while (retry--) {
702 info = amdgpu_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, ¶ms);
703 if (!info)
704 return -EIO;
705
706 memset(&atcs_output, 0, sizeof(atcs_output));
707
708 size = *(u16 *) info->buffer.pointer;
709 if (size < 3) {
710 DRM_INFO("ATCS buffer is too small: %zu\n", size);
711 kfree(info);
712 return -EINVAL;
713 }
714 size = min(sizeof(atcs_output), size);
715
716 memcpy(&atcs_output, info->buffer.pointer, size);
717
718 kfree(info);
719
720 switch (atcs_output.ret_val) {
721 case ATCS_REQUEST_REFUSED:
722 default:
723 return -EINVAL;
724 case ATCS_REQUEST_COMPLETE:
725 return 0;
726 case ATCS_REQUEST_IN_PROGRESS:
727 udelay(10);
728 break;
729 }
730 }
731
732 return 0;
733 }
734
735 /**
736 * amdgpu_acpi_event - handle notify events
737 *
738 * @nb: notifier block
739 * @val: val
740 * @data: acpi event
741 *
742 * Calls relevant amdgpu functions in response to various
743 * acpi events.
744 * Returns NOTIFY code
745 */
746 static int amdgpu_acpi_event(struct notifier_block *nb,
747 unsigned long val,
748 void *data)
749 {
750 struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, acpi_nb);
751 struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
752
753 if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
754 if (power_supply_is_system_supplied() > 0)
755 DRM_DEBUG_DRIVER("pm: AC\n");
756 else
757 DRM_DEBUG_DRIVER("pm: DC\n");
758
759 amdgpu_pm_acpi_event_handler(adev);
760 }
761
762 /* Check for pending SBIOS requests */
763 return amdgpu_atif_handler(adev, entry);
764 }
765
766 /* Call all ACPI methods here */
767 /**
768 * amdgpu_acpi_init - init driver acpi support
769 *
770 * @adev: amdgpu_device pointer
771 *
772 * Verifies the AMD ACPI interfaces and registers with the acpi
773 * notifier chain (all asics).
774 * Returns 0 on success, error on failure.
775 */
776 int amdgpu_acpi_init(struct amdgpu_device *adev)
777 {
778 acpi_handle handle, atif_handle;
779 struct amdgpu_atif *atif;
780 struct amdgpu_atcs *atcs = &adev->atcs;
781 int ret;
782
783 /* Get the device handle */
784 handle = ACPI_HANDLE(&adev->pdev->dev);
785
786 if (!adev->bios || !handle)
787 return 0;
788
789 /* Call the ATCS method */
790 ret = amdgpu_atcs_verify_interface(handle, atcs);
791 if (ret) {
792 DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
793 }
794
795 /* Probe for ATIF, and initialize it if found */
796 atif_handle = amdgpu_atif_probe_handle(handle);
797 if (!atif_handle)
798 goto out;
799
800 atif = kzalloc(sizeof(*atif), GFP_KERNEL);
801 if (!atif) {
802 DRM_WARN("Not enough memory to initialize ATIF\n");
803 goto out;
804 }
805 atif->handle = atif_handle;
806
807 /* Call the ATIF method */
808 ret = amdgpu_atif_verify_interface(atif);
809 if (ret) {
810 DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
811 kfree(atif);
812 goto out;
813 }
814 adev->atif = atif;
815
816 if (atif->notifications.brightness_change) {
817 struct drm_encoder *tmp;
818
819 /* Find the encoder controlling the brightness */
820 list_for_each_entry(tmp, &adev->ddev->mode_config.encoder_list,
821 head) {
822 struct amdgpu_encoder *enc = to_amdgpu_encoder(tmp);
823
824 if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
825 enc->enc_priv) {
826 struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
827 if (dig->bl_dev) {
828 atif->encoder_for_bl = enc;
829 break;
830 }
831 }
832 }
833 }
834
835 if (atif->functions.sbios_requests && !atif->functions.system_params) {
836 /* XXX check this workraround, if sbios request function is
837 * present we have to see how it's configured in the system
838 * params
839 */
840 atif->functions.system_params = true;
841 }
842
843 if (atif->functions.system_params) {
844 ret = amdgpu_atif_get_notification_params(atif);
845 if (ret) {
846 DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
847 ret);
848 /* Disable notification */
849 atif->notification_cfg.enabled = false;
850 }
851 }
852
853 if (atif->functions.query_backlight_transfer_characteristics) {
854 ret = amdgpu_atif_query_backlight_caps(atif);
855 if (ret) {
856 DRM_DEBUG_DRIVER("Call to QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS failed: %d\n",
857 ret);
858 atif->backlight_caps.caps_valid = false;
859 }
860 } else {
861 atif->backlight_caps.caps_valid = false;
862 }
863
864 out:
865 adev->acpi_nb.notifier_call = amdgpu_acpi_event;
866 register_acpi_notifier(&adev->acpi_nb);
867
868 return ret;
869 }
870
871 void amdgpu_acpi_get_backlight_caps(struct amdgpu_device *adev,
872 struct amdgpu_dm_backlight_caps *caps)
873 {
874 if (!adev->atif) {
875 caps->caps_valid = false;
876 return;
877 }
878 caps->caps_valid = adev->atif->backlight_caps.caps_valid;
879 caps->min_input_signal = adev->atif->backlight_caps.min_input_signal;
880 caps->max_input_signal = adev->atif->backlight_caps.max_input_signal;
881 }
882
883 /**
884 * amdgpu_acpi_fini - tear down driver acpi support
885 *
886 * @adev: amdgpu_device pointer
887 *
888 * Unregisters with the acpi notifier chain (all asics).
889 */
890 void amdgpu_acpi_fini(struct amdgpu_device *adev)
891 {
892 unregister_acpi_notifier(&adev->acpi_nb);
893 kfree(adev->atif);
894 }
895