Home | History | Annotate | Line # | Download | only in amdgpu
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(&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