801 lines · c
1/*2 * Copyright 2012 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 */23 24#include <linux/acpi.h>25#include <linux/backlight.h>26#include <linux/pci.h>27#include <linux/pm_runtime.h>28#include <linux/power_supply.h>29#include <linux/slab.h>30 31#include <acpi/acpi_bus.h>32#include <acpi/video.h>33 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#else44static inline bool radeon_atpx_dgpu_req_power_for_displays(void) { return false; }45#endif46 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 0x376#define ATIF_NOTIFY_NONE 077#define ATIF_NOTIFY_81 178#define ATIF_NOTIFY_N 279 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 0x387 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 method103 */104/**105 * radeon_atif_call - call an ATIF method106 *107 * @handle: acpi handle108 * @function: the ATIF function to execute109 * @params: ATIF function params110 *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 notifications153 *154 * @n: supported notifications struct155 * @mask: supported notifications mask from ATIF156 *157 * Use the supported notifications mask from ATIF function158 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications159 * 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 functions176 *177 * @f: supported functions struct178 * @mask: supported functions mask from ATIF179 *180 * Use the supported functions mask from ATIF function181 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions182 * 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 ATIF200 *201 * @handle: acpi handle202 * @atif: radeon atif struct203 *204 * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function205 * to initialize ATIF and determine what features are supported206 * (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 configuration246 *247 * @handle: acpi handle248 * @n: atif notification configuration struct249 *250 * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function251 * to determine if a notifier is used and if so which one252 * (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(¶ms, 0, sizeof(params));277 size = min(sizeof(params), size);278 memcpy(¶ms, 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 event309 *310 * @handle: acpi handle311 * @req: atif sbios request struct312 *313 * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function314 * to determine what requests the sbios is making to the driver315 * (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 requests349 *350 * @rdev: radeon_device pointer351 * @event: atif sbios request struct352 *353 * Checks the acpi event and if it matches an atif event,354 * handles it.355 * Returns NOTIFY code356 */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 (rdev->is_atom_bios) {395 struct radeon_encoder_atom_dig *dig = enc->enc_priv;396 backlight_force_update(dig->bl_dev,397 BACKLIGHT_UPDATE_HOTKEY);398 } else {399 struct radeon_encoder_lvds *dig = enc->enc_priv;400 backlight_force_update(dig->bl_dev,401 BACKLIGHT_UPDATE_HOTKEY);402 }403 }404 }405 if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {406 if ((rdev->flags & RADEON_IS_PX) &&407 radeon_atpx_dgpu_req_power_for_displays()) {408 pm_runtime_get_sync(rdev_to_drm(rdev)->dev);409 /* Just fire off a uevent and let userspace tell us what to do */410 drm_helper_hpd_irq_event(rdev_to_drm(rdev));411 pm_runtime_mark_last_busy(rdev_to_drm(rdev)->dev);412 pm_runtime_put_autosuspend(rdev_to_drm(rdev)->dev);413 }414 }415 /* TODO: check other events */416 417 /* We've handled the event, stop the notifier chain. The ACPI interface418 * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to419 * userspace if the event was generated only to signal a SBIOS420 * request.421 */422 return NOTIFY_BAD;423}424 425/* Call the ATCS method426 */427/**428 * radeon_atcs_call - call an ATCS method429 *430 * @handle: acpi handle431 * @function: the ATCS function to execute432 * @params: ATCS function params433 *434 * Executes the requested ATCS function (all asics).435 * Returns a pointer to the acpi output buffer.436 */437static union acpi_object *radeon_atcs_call(acpi_handle handle, int function,438 struct acpi_buffer *params)439{440 acpi_status status;441 union acpi_object atcs_arg_elements[2];442 struct acpi_object_list atcs_arg;443 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };444 445 atcs_arg.count = 2;446 atcs_arg.pointer = &atcs_arg_elements[0];447 448 atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;449 atcs_arg_elements[0].integer.value = function;450 451 if (params) {452 atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;453 atcs_arg_elements[1].buffer.length = params->length;454 atcs_arg_elements[1].buffer.pointer = params->pointer;455 } else {456 /* We need a second fake parameter */457 atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;458 atcs_arg_elements[1].integer.value = 0;459 }460 461 status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer);462 463 /* Fail only if calling the method fails and ATIF is supported */464 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {465 DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",466 acpi_format_exception(status));467 kfree(buffer.pointer);468 return NULL;469 }470 471 return buffer.pointer;472}473 474/**475 * radeon_atcs_parse_functions - parse supported functions476 *477 * @f: supported functions struct478 * @mask: supported functions mask from ATCS479 *480 * Use the supported functions mask from ATCS function481 * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions482 * are supported (all asics).483 */484static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask)485{486 f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;487 f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;488 f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;489 f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;490}491 492/**493 * radeon_atcs_verify_interface - verify ATCS494 *495 * @handle: acpi handle496 * @atcs: radeon atcs struct497 *498 * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function499 * to initialize ATCS and determine what features are supported500 * (all asics).501 * returns 0 on success, error on failure.502 */503static int radeon_atcs_verify_interface(acpi_handle handle,504 struct radeon_atcs *atcs)505{506 union acpi_object *info;507 struct atcs_verify_interface output;508 size_t size;509 int err = 0;510 511 info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);512 if (!info)513 return -EIO;514 515 memset(&output, 0, sizeof(output));516 517 size = *(u16 *) info->buffer.pointer;518 if (size < 8) {519 DRM_INFO("ATCS buffer is too small: %zu\n", size);520 err = -EINVAL;521 goto out;522 }523 size = min(sizeof(output), size);524 525 memcpy(&output, info->buffer.pointer, size);526 527 /* TODO: check version? */528 DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);529 530 radeon_atcs_parse_functions(&atcs->functions, output.function_bits);531 532out:533 kfree(info);534 return err;535}536 537/**538 * radeon_acpi_is_pcie_performance_request_supported539 *540 * @rdev: radeon_device pointer541 *542 * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods543 * are supported (all asics).544 * returns true if supported, false if not.545 */546bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev)547{548 struct radeon_atcs *atcs = &rdev->atcs;549 550 if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)551 return true;552 553 return false;554}555 556/**557 * radeon_acpi_pcie_notify_device_ready558 *559 * @rdev: radeon_device pointer560 *561 * Executes the PCIE_DEVICE_READY_NOTIFICATION method562 * (all asics).563 * returns 0 on success, error on failure.564 */565int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev)566{567 acpi_handle handle;568 union acpi_object *info;569 struct radeon_atcs *atcs = &rdev->atcs;570 571 /* Get the device handle */572 handle = ACPI_HANDLE(&rdev->pdev->dev);573 if (!handle)574 return -EINVAL;575 576 if (!atcs->functions.pcie_dev_rdy)577 return -EINVAL;578 579 info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);580 if (!info)581 return -EIO;582 583 kfree(info);584 585 return 0;586}587 588/**589 * radeon_acpi_pcie_performance_request590 *591 * @rdev: radeon_device pointer592 * @perf_req: requested perf level (pcie gen speed)593 * @advertise: set advertise caps flag if set594 *595 * Executes the PCIE_PERFORMANCE_REQUEST method to596 * change the pcie gen speed (all asics).597 * returns 0 on success, error on failure.598 */599int radeon_acpi_pcie_performance_request(struct radeon_device *rdev,600 u8 perf_req, bool advertise)601{602 acpi_handle handle;603 union acpi_object *info;604 struct radeon_atcs *atcs = &rdev->atcs;605 struct atcs_pref_req_input atcs_input;606 struct atcs_pref_req_output atcs_output;607 struct acpi_buffer params;608 size_t size;609 u32 retry = 3;610 611 /* Get the device handle */612 handle = ACPI_HANDLE(&rdev->pdev->dev);613 if (!handle)614 return -EINVAL;615 616 if (!atcs->functions.pcie_perf_req)617 return -EINVAL;618 619 atcs_input.size = sizeof(struct atcs_pref_req_input);620 /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */621 atcs_input.client_id = pci_dev_id(rdev->pdev);622 atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;623 atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;624 if (advertise)625 atcs_input.flags |= ATCS_ADVERTISE_CAPS;626 atcs_input.req_type = ATCS_PCIE_LINK_SPEED;627 atcs_input.perf_req = perf_req;628 629 params.length = sizeof(struct atcs_pref_req_input);630 params.pointer = &atcs_input;631 632 while (retry--) {633 info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, ¶ms);634 if (!info)635 return -EIO;636 637 memset(&atcs_output, 0, sizeof(atcs_output));638 639 size = *(u16 *) info->buffer.pointer;640 if (size < 3) {641 DRM_INFO("ATCS buffer is too small: %zu\n", size);642 kfree(info);643 return -EINVAL;644 }645 size = min(sizeof(atcs_output), size);646 647 memcpy(&atcs_output, info->buffer.pointer, size);648 649 kfree(info);650 651 switch (atcs_output.ret_val) {652 case ATCS_REQUEST_REFUSED:653 default:654 return -EINVAL;655 case ATCS_REQUEST_COMPLETE:656 return 0;657 case ATCS_REQUEST_IN_PROGRESS:658 udelay(10);659 break;660 }661 }662 663 return 0;664}665 666/**667 * radeon_acpi_event - handle notify events668 *669 * @nb: notifier block670 * @val: val671 * @data: acpi event672 *673 * Calls relevant radeon functions in response to various674 * acpi events.675 * Returns NOTIFY code676 */677static int radeon_acpi_event(struct notifier_block *nb,678 unsigned long val,679 void *data)680{681 struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb);682 struct acpi_bus_event *entry = (struct acpi_bus_event *)data;683 684 if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {685 if (power_supply_is_system_supplied() > 0)686 DRM_DEBUG_DRIVER("pm: AC\n");687 else688 DRM_DEBUG_DRIVER("pm: DC\n");689 690 radeon_pm_acpi_event_handler(rdev);691 }692 693 /* Check for pending SBIOS requests */694 return radeon_atif_handler(rdev, entry);695}696 697/* Call all ACPI methods here */698/**699 * radeon_acpi_init - init driver acpi support700 *701 * @rdev: radeon_device pointer702 *703 * Verifies the AMD ACPI interfaces and registers with the acpi704 * notifier chain (all asics).705 * Returns 0 on success, error on failure.706 */707int radeon_acpi_init(struct radeon_device *rdev)708{709 acpi_handle handle;710 struct radeon_atif *atif = &rdev->atif;711 struct radeon_atcs *atcs = &rdev->atcs;712 int ret;713 714 /* Get the device handle */715 handle = ACPI_HANDLE(&rdev->pdev->dev);716 717 /* No need to proceed if we're sure that ATIF is not supported */718 if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)719 return 0;720 721 /* Call the ATCS method */722 ret = radeon_atcs_verify_interface(handle, atcs);723 if (ret) {724 DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);725 }726 727 /* Call the ATIF method */728 ret = radeon_atif_verify_interface(handle, atif);729 if (ret) {730 DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);731 goto out;732 }733 734 if (atif->notifications.brightness_change) {735 struct drm_encoder *tmp;736 struct radeon_encoder *target = NULL;737 738 /* Find the encoder controlling the brightness */739 list_for_each_entry(tmp, &rdev_to_drm(rdev)->mode_config.encoder_list,740 head) {741 struct radeon_encoder *enc = to_radeon_encoder(tmp);742 743 if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&744 enc->enc_priv) {745 if (rdev->is_atom_bios) {746 struct radeon_encoder_atom_dig *dig = enc->enc_priv;747 if (dig->bl_dev) {748 target = enc;749 break;750 }751 } else {752 struct radeon_encoder_lvds *dig = enc->enc_priv;753 if (dig->bl_dev) {754 target = enc;755 break;756 }757 }758 }759 }760 761 atif->encoder_for_bl = target;762 }763 764 if (atif->functions.sbios_requests && !atif->functions.system_params) {765 /* XXX check this workraround, if sbios request function is766 * present we have to see how it's configured in the system767 * params768 */769 atif->functions.system_params = true;770 }771 772 if (atif->functions.system_params) {773 ret = radeon_atif_get_notification_params(handle,774 &atif->notification_cfg);775 if (ret) {776 DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",777 ret);778 /* Disable notification */779 atif->notification_cfg.enabled = false;780 }781 }782 783out:784 rdev->acpi_nb.notifier_call = radeon_acpi_event;785 register_acpi_notifier(&rdev->acpi_nb);786 787 return ret;788}789 790/**791 * radeon_acpi_fini - tear down driver acpi support792 *793 * @rdev: radeon_device pointer794 *795 * Unregisters with the acpi notifier chain (all asics).796 */797void radeon_acpi_fini(struct radeon_device *rdev)798{799 unregister_acpi_notifier(&rdev->acpi_nb);800}801