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