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