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