cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

radeon_acpi.c (22745B)


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