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