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