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 <linux/pm_runtime.h>
  29#include <acpi/video.h>
  30#include <acpi/actbl.h>
  31
  32#include <drm/drm_crtc_helper.h>
  33#include "amdgpu.h"
  34#include "amdgpu_pm.h"
  35#include "amdgpu_display.h"
  36#include "amd_acpi.h"
  37#include "atom.h"
  38
  39struct amdgpu_atif_notification_cfg {
  40        bool enabled;
  41        int command_code;
  42};
  43
  44struct amdgpu_atif_notifications {
  45        bool thermal_state;
  46        bool forced_power_state;
  47        bool system_power_state;
  48        bool brightness_change;
  49        bool dgpu_display_event;
  50        bool gpu_package_power_limit;
  51};
  52
  53struct amdgpu_atif_functions {
  54        bool system_params;
  55        bool sbios_requests;
  56        bool temperature_change;
  57        bool query_backlight_transfer_characteristics;
  58        bool ready_to_undock;
  59        bool external_gpu_information;
  60};
  61
  62struct amdgpu_atif {
  63        acpi_handle handle;
  64
  65        struct amdgpu_atif_notifications notifications;
  66        struct amdgpu_atif_functions functions;
  67        struct amdgpu_atif_notification_cfg notification_cfg;
  68#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
  69        struct backlight_device *bd;
  70#endif
  71        struct amdgpu_dm_backlight_caps backlight_caps;
  72};
  73
  74/* Call the ATIF method
  75 */
  76/**
  77 * amdgpu_atif_call - call an ATIF method
  78 *
  79 * @handle: acpi handle
  80 * @function: the ATIF function to execute
  81 * @params: ATIF function params
  82 *
  83 * Executes the requested ATIF function (all asics).
  84 * Returns a pointer to the acpi output buffer.
  85 */
  86static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
  87                                           int function,
  88                                           struct acpi_buffer *params)
  89{
  90        acpi_status status;
  91        union acpi_object atif_arg_elements[2];
  92        struct acpi_object_list atif_arg;
  93        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  94
  95        atif_arg.count = 2;
  96        atif_arg.pointer = &atif_arg_elements[0];
  97
  98        atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
  99        atif_arg_elements[0].integer.value = function;
 100
 101        if (params) {
 102                atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
 103                atif_arg_elements[1].buffer.length = params->length;
 104                atif_arg_elements[1].buffer.pointer = params->pointer;
 105        } else {
 106                /* We need a second fake parameter */
 107                atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
 108                atif_arg_elements[1].integer.value = 0;
 109        }
 110
 111        status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
 112                                      &buffer);
 113
 114        /* Fail only if calling the method fails and ATIF is supported */
 115        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
 116                DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
 117                                 acpi_format_exception(status));
 118                kfree(buffer.pointer);
 119                return NULL;
 120        }
 121
 122        return buffer.pointer;
 123}
 124
 125/**
 126 * amdgpu_atif_parse_notification - parse supported notifications
 127 *
 128 * @n: supported notifications struct
 129 * @mask: supported notifications mask from ATIF
 130 *
 131 * Use the supported notifications mask from ATIF function
 132 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications
 133 * are supported (all asics).
 134 */
 135static void amdgpu_atif_parse_notification(struct amdgpu_atif_notifications *n, u32 mask)
 136{
 137        n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
 138        n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
 139        n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
 140        n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
 141        n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
 142        n->gpu_package_power_limit = mask & ATIF_GPU_PACKAGE_POWER_LIMIT_REQUEST_SUPPORTED;
 143}
 144
 145/**
 146 * amdgpu_atif_parse_functions - parse supported functions
 147 *
 148 * @f: supported functions struct
 149 * @mask: supported functions mask from ATIF
 150 *
 151 * Use the supported functions mask from ATIF function
 152 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions
 153 * are supported (all asics).
 154 */
 155static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mask)
 156{
 157        f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
 158        f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
 159        f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
 160        f->query_backlight_transfer_characteristics =
 161                mask & ATIF_QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS_SUPPORTED;
 162        f->ready_to_undock = mask & ATIF_READY_TO_UNDOCK_NOTIFICATION_SUPPORTED;
 163        f->external_gpu_information = mask & ATIF_GET_EXTERNAL_GPU_INFORMATION_SUPPORTED;
 164}
 165
 166/**
 167 * amdgpu_atif_verify_interface - verify ATIF
 168 *
 169 * @handle: acpi handle
 170 * @atif: amdgpu atif struct
 171 *
 172 * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function
 173 * to initialize ATIF and determine what features are supported
 174 * (all asics).
 175 * returns 0 on success, error on failure.
 176 */
 177static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif)
 178{
 179        union acpi_object *info;
 180        struct atif_verify_interface output;
 181        size_t size;
 182        int err = 0;
 183
 184        info = amdgpu_atif_call(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
 185        if (!info)
 186                return -EIO;
 187
 188        memset(&output, 0, sizeof(output));
 189
 190        size = *(u16 *) info->buffer.pointer;
 191        if (size < 12) {
 192                DRM_INFO("ATIF buffer is too small: %zu\n", size);
 193                err = -EINVAL;
 194                goto out;
 195        }
 196        size = min(sizeof(output), size);
 197
 198        memcpy(&output, info->buffer.pointer, size);
 199
 200        /* TODO: check version? */
 201        DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
 202
 203        amdgpu_atif_parse_notification(&atif->notifications, output.notification_mask);
 204        amdgpu_atif_parse_functions(&atif->functions, output.function_bits);
 205
 206out:
 207        kfree(info);
 208        return err;
 209}
 210
 211static acpi_handle amdgpu_atif_probe_handle(acpi_handle dhandle)
 212{
 213        acpi_handle handle = NULL;
 214        char acpi_method_name[255] = { 0 };
 215        struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name };
 216        acpi_status status;
 217
 218        /* For PX/HG systems, ATIF and ATPX are in the iGPU's namespace, on dGPU only
 219         * systems, ATIF is in the dGPU's namespace.
 220         */
 221        status = acpi_get_handle(dhandle, "ATIF", &handle);
 222        if (ACPI_SUCCESS(status))
 223                goto out;
 224
 225        if (amdgpu_has_atpx()) {
 226                status = acpi_get_handle(amdgpu_atpx_get_dhandle(), "ATIF",
 227                                         &handle);
 228                if (ACPI_SUCCESS(status))
 229                        goto out;
 230        }
 231
 232        DRM_DEBUG_DRIVER("No ATIF handle found\n");
 233        return NULL;
 234out:
 235        acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 236        DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name);
 237        return handle;
 238}
 239
 240/**
 241 * amdgpu_atif_get_notification_params - determine notify configuration
 242 *
 243 * @handle: acpi handle
 244 * @n: atif notification configuration struct
 245 *
 246 * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function
 247 * to determine if a notifier is used and if so which one
 248 * (all asics).  This is either Notify(VGA, 0x81) or Notify(VGA, n)
 249 * where n is specified in the result if a notifier is used.
 250 * Returns 0 on success, error on failure.
 251 */
 252static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)
 253{
 254        union acpi_object *info;
 255        struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg;
 256        struct atif_system_params params;
 257        size_t size;
 258        int err = 0;
 259
 260        info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS,
 261                                NULL);
 262        if (!info) {
 263                err = -EIO;
 264                goto out;
 265        }
 266
 267        size = *(u16 *) info->buffer.pointer;
 268        if (size < 10) {
 269                err = -EINVAL;
 270                goto out;
 271        }
 272
 273        memset(&params, 0, sizeof(params));
 274        size = min(sizeof(params), size);
 275        memcpy(&params, info->buffer.pointer, size);
 276
 277        DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
 278                        params.flags, params.valid_mask);
 279        params.flags = params.flags & params.valid_mask;
 280
 281        if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
 282                n->enabled = false;
 283                n->command_code = 0;
 284        } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
 285                n->enabled = true;
 286                n->command_code = 0x81;
 287        } else {
 288                if (size < 11) {
 289                        err = -EINVAL;
 290                        goto out;
 291                }
 292                n->enabled = true;
 293                n->command_code = params.command_code;
 294        }
 295
 296out:
 297        DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
 298                        (n->enabled ? "enabled" : "disabled"),
 299                        n->command_code);
 300        kfree(info);
 301        return err;
 302}
 303
 304/**
 305 * amdgpu_atif_query_backlight_caps - get min and max backlight input signal
 306 *
 307 * @handle: acpi handle
 308 *
 309 * Execute the QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS ATIF function
 310 * to determine the acceptable range of backlight values
 311 *
 312 * Backlight_caps.caps_valid will be set to true if the query is successful
 313 *
 314 * The input signals are in range 0-255
 315 *
 316 * This function assumes the display with backlight is the first LCD
 317 *
 318 * Returns 0 on success, error on failure.
 319 */
 320static int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif)
 321{
 322        union acpi_object *info;
 323        struct atif_qbtc_output characteristics;
 324        struct atif_qbtc_arguments arguments;
 325        struct acpi_buffer params;
 326        size_t size;
 327        int err = 0;
 328
 329        arguments.size = sizeof(arguments);
 330        arguments.requested_display = ATIF_QBTC_REQUEST_LCD1;
 331
 332        params.length = sizeof(arguments);
 333        params.pointer = (void *)&arguments;
 334
 335        info = amdgpu_atif_call(atif,
 336                ATIF_FUNCTION_QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS,
 337                &params);
 338        if (!info) {
 339                err = -EIO;
 340                goto out;
 341        }
 342
 343        size = *(u16 *) info->buffer.pointer;
 344        if (size < 10) {
 345                err = -EINVAL;
 346                goto out;
 347        }
 348
 349        memset(&characteristics, 0, sizeof(characteristics));
 350        size = min(sizeof(characteristics), size);
 351        memcpy(&characteristics, info->buffer.pointer, size);
 352
 353        atif->backlight_caps.caps_valid = true;
 354        atif->backlight_caps.min_input_signal =
 355                        characteristics.min_input_signal;
 356        atif->backlight_caps.max_input_signal =
 357                        characteristics.max_input_signal;
 358out:
 359        kfree(info);
 360        return err;
 361}
 362
 363/**
 364 * amdgpu_atif_get_sbios_requests - get requested sbios event
 365 *
 366 * @handle: acpi handle
 367 * @req: atif sbios request struct
 368 *
 369 * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function
 370 * to determine what requests the sbios is making to the driver
 371 * (all asics).
 372 * Returns 0 on success, error on failure.
 373 */
 374static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif,
 375                                          struct atif_sbios_requests *req)
 376{
 377        union acpi_object *info;
 378        size_t size;
 379        int count = 0;
 380
 381        info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS,
 382                                NULL);
 383        if (!info)
 384                return -EIO;
 385
 386        size = *(u16 *)info->buffer.pointer;
 387        if (size < 0xd) {
 388                count = -EINVAL;
 389                goto out;
 390        }
 391        memset(req, 0, sizeof(*req));
 392
 393        size = min(sizeof(*req), size);
 394        memcpy(req, info->buffer.pointer, size);
 395        DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
 396
 397        count = hweight32(req->pending);
 398
 399out:
 400        kfree(info);
 401        return count;
 402}
 403
 404/**
 405 * amdgpu_atif_handler - handle ATIF notify requests
 406 *
 407 * @adev: amdgpu_device pointer
 408 * @event: atif sbios request struct
 409 *
 410 * Checks the acpi event and if it matches an atif event,
 411 * handles it.
 412 *
 413 * Returns:
 414 * NOTIFY_BAD or NOTIFY_DONE, depending on the event.
 415 */
 416static int amdgpu_atif_handler(struct amdgpu_device *adev,
 417                               struct acpi_bus_event *event)
 418{
 419        struct amdgpu_atif *atif = adev->atif;
 420        int count;
 421
 422        DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
 423                        event->device_class, event->type);
 424
 425        if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
 426                return NOTIFY_DONE;
 427
 428        /* Is this actually our event? */
 429        if (!atif ||
 430            !atif->notification_cfg.enabled ||
 431            event->type != atif->notification_cfg.command_code) {
 432                /* These events will generate keypresses otherwise */
 433                if (event->type == ACPI_VIDEO_NOTIFY_PROBE)
 434                        return NOTIFY_BAD;
 435                else
 436                        return NOTIFY_DONE;
 437        }
 438
 439        if (atif->functions.sbios_requests) {
 440                struct atif_sbios_requests req;
 441
 442                /* Check pending SBIOS requests */
 443                count = amdgpu_atif_get_sbios_requests(atif, &req);
 444
 445                if (count <= 0)
 446                        return NOTIFY_BAD;
 447
 448                DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
 449
 450                if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
 451#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
 452                        if (atif->bd) {
 453                                DRM_DEBUG_DRIVER("Changing brightness to %d\n",
 454                                                 req.backlight_level);
 455                                /*
 456                                 * XXX backlight_device_set_brightness() is
 457                                 * hardwired to post BACKLIGHT_UPDATE_SYSFS.
 458                                 * It probably should accept 'reason' parameter.
 459                                 */
 460                                backlight_device_set_brightness(atif->bd, req.backlight_level);
 461                        }
 462#endif
 463                }
 464
 465                if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
 466                        if (adev->flags & AMD_IS_PX) {
 467                                pm_runtime_get_sync(adev_to_drm(adev)->dev);
 468                                /* Just fire off a uevent and let userspace tell us what to do */
 469                                drm_helper_hpd_irq_event(adev_to_drm(adev));
 470                                pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
 471                                pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 472                        }
 473                }
 474                /* TODO: check other events */
 475        }
 476
 477        /* We've handled the event, stop the notifier chain. The ACPI interface
 478         * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
 479         * userspace if the event was generated only to signal a SBIOS
 480         * request.
 481         */
 482        return NOTIFY_BAD;
 483}
 484
 485/* Call the ATCS method
 486 */
 487/**
 488 * amdgpu_atcs_call - call an ATCS method
 489 *
 490 * @handle: acpi handle
 491 * @function: the ATCS function to execute
 492 * @params: ATCS function params
 493 *
 494 * Executes the requested ATCS function (all asics).
 495 * Returns a pointer to the acpi output buffer.
 496 */
 497static union acpi_object *amdgpu_atcs_call(acpi_handle handle, int function,
 498                                           struct acpi_buffer *params)
 499{
 500        acpi_status status;
 501        union acpi_object atcs_arg_elements[2];
 502        struct acpi_object_list atcs_arg;
 503        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 504
 505        atcs_arg.count = 2;
 506        atcs_arg.pointer = &atcs_arg_elements[0];
 507
 508        atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;
 509        atcs_arg_elements[0].integer.value = function;
 510
 511        if (params) {
 512                atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;
 513                atcs_arg_elements[1].buffer.length = params->length;
 514                atcs_arg_elements[1].buffer.pointer = params->pointer;
 515        } else {
 516                /* We need a second fake parameter */
 517                atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;
 518                atcs_arg_elements[1].integer.value = 0;
 519        }
 520
 521        status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer);
 522
 523        /* Fail only if calling the method fails and ATIF is supported */
 524        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
 525                DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
 526                                 acpi_format_exception(status));
 527                kfree(buffer.pointer);
 528                return NULL;
 529        }
 530
 531        return buffer.pointer;
 532}
 533
 534/**
 535 * amdgpu_atcs_parse_functions - parse supported functions
 536 *
 537 * @f: supported functions struct
 538 * @mask: supported functions mask from ATCS
 539 *
 540 * Use the supported functions mask from ATCS function
 541 * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
 542 * are supported (all asics).
 543 */
 544static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mask)
 545{
 546        f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
 547        f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
 548        f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
 549        f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
 550}
 551
 552/**
 553 * amdgpu_atcs_verify_interface - verify ATCS
 554 *
 555 * @handle: acpi handle
 556 * @atcs: amdgpu atcs struct
 557 *
 558 * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
 559 * to initialize ATCS and determine what features are supported
 560 * (all asics).
 561 * returns 0 on success, error on failure.
 562 */
 563static int amdgpu_atcs_verify_interface(acpi_handle handle,
 564                                        struct amdgpu_atcs *atcs)
 565{
 566        union acpi_object *info;
 567        struct atcs_verify_interface output;
 568        size_t size;
 569        int err = 0;
 570
 571        info = amdgpu_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
 572        if (!info)
 573                return -EIO;
 574
 575        memset(&output, 0, sizeof(output));
 576
 577        size = *(u16 *) info->buffer.pointer;
 578        if (size < 8) {
 579                DRM_INFO("ATCS buffer is too small: %zu\n", size);
 580                err = -EINVAL;
 581                goto out;
 582        }
 583        size = min(sizeof(output), size);
 584
 585        memcpy(&output, info->buffer.pointer, size);
 586
 587        /* TODO: check version? */
 588        DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
 589
 590        amdgpu_atcs_parse_functions(&atcs->functions, output.function_bits);
 591
 592out:
 593        kfree(info);
 594        return err;
 595}
 596
 597/**
 598 * amdgpu_acpi_is_pcie_performance_request_supported
 599 *
 600 * @adev: amdgpu_device pointer
 601 *
 602 * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods
 603 * are supported (all asics).
 604 * returns true if supported, false if not.
 605 */
 606bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev)
 607{
 608        struct amdgpu_atcs *atcs = &adev->atcs;
 609
 610        if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)
 611                return true;
 612
 613        return false;
 614}
 615
 616/**
 617 * amdgpu_acpi_pcie_notify_device_ready
 618 *
 619 * @adev: amdgpu_device pointer
 620 *
 621 * Executes the PCIE_DEVICE_READY_NOTIFICATION method
 622 * (all asics).
 623 * returns 0 on success, error on failure.
 624 */
 625int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev)
 626{
 627        acpi_handle handle;
 628        union acpi_object *info;
 629        struct amdgpu_atcs *atcs = &adev->atcs;
 630
 631        /* Get the device handle */
 632        handle = ACPI_HANDLE(&adev->pdev->dev);
 633        if (!handle)
 634                return -EINVAL;
 635
 636        if (!atcs->functions.pcie_dev_rdy)
 637                return -EINVAL;
 638
 639        info = amdgpu_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
 640        if (!info)
 641                return -EIO;
 642
 643        kfree(info);
 644
 645        return 0;
 646}
 647
 648/**
 649 * amdgpu_acpi_pcie_performance_request
 650 *
 651 * @adev: amdgpu_device pointer
 652 * @perf_req: requested perf level (pcie gen speed)
 653 * @advertise: set advertise caps flag if set
 654 *
 655 * Executes the PCIE_PERFORMANCE_REQUEST method to
 656 * change the pcie gen speed (all asics).
 657 * returns 0 on success, error on failure.
 658 */
 659int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
 660                                         u8 perf_req, bool advertise)
 661{
 662        acpi_handle handle;
 663        union acpi_object *info;
 664        struct amdgpu_atcs *atcs = &adev->atcs;
 665        struct atcs_pref_req_input atcs_input;
 666        struct atcs_pref_req_output atcs_output;
 667        struct acpi_buffer params;
 668        size_t size;
 669        u32 retry = 3;
 670
 671        if (amdgpu_acpi_pcie_notify_device_ready(adev))
 672                return -EINVAL;
 673
 674        /* Get the device handle */
 675        handle = ACPI_HANDLE(&adev->pdev->dev);
 676        if (!handle)
 677                return -EINVAL;
 678
 679        if (!atcs->functions.pcie_perf_req)
 680                return -EINVAL;
 681
 682        atcs_input.size = sizeof(struct atcs_pref_req_input);
 683        /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
 684        atcs_input.client_id = adev->pdev->devfn | (adev->pdev->bus->number << 8);
 685        atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
 686        atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
 687        if (advertise)
 688                atcs_input.flags |= ATCS_ADVERTISE_CAPS;
 689        atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
 690        atcs_input.perf_req = perf_req;
 691
 692        params.length = sizeof(struct atcs_pref_req_input);
 693        params.pointer = &atcs_input;
 694
 695        while (retry--) {
 696                info = amdgpu_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, &params);
 697                if (!info)
 698                        return -EIO;
 699
 700                memset(&atcs_output, 0, sizeof(atcs_output));
 701
 702                size = *(u16 *) info->buffer.pointer;
 703                if (size < 3) {
 704                        DRM_INFO("ATCS buffer is too small: %zu\n", size);
 705                        kfree(info);
 706                        return -EINVAL;
 707                }
 708                size = min(sizeof(atcs_output), size);
 709
 710                memcpy(&atcs_output, info->buffer.pointer, size);
 711
 712                kfree(info);
 713
 714                switch (atcs_output.ret_val) {
 715                case ATCS_REQUEST_REFUSED:
 716                default:
 717                        return -EINVAL;
 718                case ATCS_REQUEST_COMPLETE:
 719                        return 0;
 720                case ATCS_REQUEST_IN_PROGRESS:
 721                        udelay(10);
 722                        break;
 723                }
 724        }
 725
 726        return 0;
 727}
 728
 729/**
 730 * amdgpu_acpi_event - handle notify events
 731 *
 732 * @nb: notifier block
 733 * @val: val
 734 * @data: acpi event
 735 *
 736 * Calls relevant amdgpu functions in response to various
 737 * acpi events.
 738 * Returns NOTIFY code
 739 */
 740static int amdgpu_acpi_event(struct notifier_block *nb,
 741                             unsigned long val,
 742                             void *data)
 743{
 744        struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, acpi_nb);
 745        struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
 746
 747        if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
 748                if (power_supply_is_system_supplied() > 0)
 749                        DRM_DEBUG_DRIVER("pm: AC\n");
 750                else
 751                        DRM_DEBUG_DRIVER("pm: DC\n");
 752
 753                amdgpu_pm_acpi_event_handler(adev);
 754        }
 755
 756        /* Check for pending SBIOS requests */
 757        return amdgpu_atif_handler(adev, entry);
 758}
 759
 760/* Call all ACPI methods here */
 761/**
 762 * amdgpu_acpi_init - init driver acpi support
 763 *
 764 * @adev: amdgpu_device pointer
 765 *
 766 * Verifies the AMD ACPI interfaces and registers with the acpi
 767 * notifier chain (all asics).
 768 * Returns 0 on success, error on failure.
 769 */
 770int amdgpu_acpi_init(struct amdgpu_device *adev)
 771{
 772        acpi_handle handle, atif_handle;
 773        struct amdgpu_atif *atif;
 774        struct amdgpu_atcs *atcs = &adev->atcs;
 775        int ret;
 776
 777        /* Get the device handle */
 778        handle = ACPI_HANDLE(&adev->pdev->dev);
 779
 780        if (!adev->bios || !handle)
 781                return 0;
 782
 783        /* Call the ATCS method */
 784        ret = amdgpu_atcs_verify_interface(handle, atcs);
 785        if (ret) {
 786                DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
 787        }
 788
 789        /* Probe for ATIF, and initialize it if found */
 790        atif_handle = amdgpu_atif_probe_handle(handle);
 791        if (!atif_handle)
 792                goto out;
 793
 794        atif = kzalloc(sizeof(*atif), GFP_KERNEL);
 795        if (!atif) {
 796                DRM_WARN("Not enough memory to initialize ATIF\n");
 797                goto out;
 798        }
 799        atif->handle = atif_handle;
 800
 801        /* Call the ATIF method */
 802        ret = amdgpu_atif_verify_interface(atif);
 803        if (ret) {
 804                DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
 805                kfree(atif);
 806                goto out;
 807        }
 808        adev->atif = atif;
 809
 810#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
 811        if (atif->notifications.brightness_change) {
 812                if (amdgpu_device_has_dc_support(adev)) {
 813#if defined(CONFIG_DRM_AMD_DC)
 814                        struct amdgpu_display_manager *dm = &adev->dm;
 815                        atif->bd = dm->backlight_dev;
 816#endif
 817                } else {
 818                        struct drm_encoder *tmp;
 819
 820                        /* Find the encoder controlling the brightness */
 821                        list_for_each_entry(tmp, &adev_to_drm(adev)->mode_config.encoder_list,
 822                                            head) {
 823                                struct amdgpu_encoder *enc = to_amdgpu_encoder(tmp);
 824
 825                                if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
 826                                    enc->enc_priv) {
 827                                        struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
 828                                        if (dig->bl_dev) {
 829                                                atif->bd = dig->bl_dev;
 830                                                break;
 831                                        }
 832                                }
 833                        }
 834                }
 835        }
 836#endif
 837
 838        if (atif->functions.sbios_requests && !atif->functions.system_params) {
 839                /* XXX check this workraround, if sbios request function is
 840                 * present we have to see how it's configured in the system
 841                 * params
 842                 */
 843                atif->functions.system_params = true;
 844        }
 845
 846        if (atif->functions.system_params) {
 847                ret = amdgpu_atif_get_notification_params(atif);
 848                if (ret) {
 849                        DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
 850                                        ret);
 851                        /* Disable notification */
 852                        atif->notification_cfg.enabled = false;
 853                }
 854        }
 855
 856        if (atif->functions.query_backlight_transfer_characteristics) {
 857                ret = amdgpu_atif_query_backlight_caps(atif);
 858                if (ret) {
 859                        DRM_DEBUG_DRIVER("Call to QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS failed: %d\n",
 860                                        ret);
 861                        atif->backlight_caps.caps_valid = false;
 862                }
 863        } else {
 864                atif->backlight_caps.caps_valid = false;
 865        }
 866
 867out:
 868        adev->acpi_nb.notifier_call = amdgpu_acpi_event;
 869        register_acpi_notifier(&adev->acpi_nb);
 870
 871        return ret;
 872}
 873
 874void amdgpu_acpi_get_backlight_caps(struct amdgpu_device *adev,
 875                struct amdgpu_dm_backlight_caps *caps)
 876{
 877        if (!adev->atif) {
 878                caps->caps_valid = false;
 879                return;
 880        }
 881        caps->caps_valid = adev->atif->backlight_caps.caps_valid;
 882        caps->min_input_signal = adev->atif->backlight_caps.min_input_signal;
 883        caps->max_input_signal = adev->atif->backlight_caps.max_input_signal;
 884}
 885
 886/**
 887 * amdgpu_acpi_fini - tear down driver acpi support
 888 *
 889 * @adev: amdgpu_device pointer
 890 *
 891 * Unregisters with the acpi notifier chain (all asics).
 892 */
 893void amdgpu_acpi_fini(struct amdgpu_device *adev)
 894{
 895        unregister_acpi_notifier(&adev->acpi_nb);
 896        kfree(adev->atif);
 897}
 898
 899/**
 900 * amdgpu_acpi_is_s0ix_supported
 901 *
 902 * returns true if supported, false if not.
 903 */
 904bool amdgpu_acpi_is_s0ix_supported(struct amdgpu_device *adev)
 905{
 906        if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
 907                if (adev->flags & AMD_IS_APU)
 908                        return true;
 909        }
 910
 911        return false;
 912}
 913