xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_acpi.c (revision 53b02e147d4ed531c0d2a5ca9b3e8026ba3e99b5)
1 /*	$NetBSD: amdgpu_acpi.c,v 1.4 2021/12/18 23:44:58 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.4 2021/12/18 23:44:58 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(&params, 0, sizeof(params));
276 	size = min(sizeof(params), size);
277 	memcpy(&params, 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 		&params);
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, &params);
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