root/drivers/gpu/drm/radeon/radeon_acpi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. radeon_atpx_dgpu_req_power_for_displays
  2. radeon_atif_call
  3. radeon_atif_parse_notification
  4. radeon_atif_parse_functions
  5. radeon_atif_verify_interface
  6. radeon_atif_get_notification_params
  7. radeon_atif_get_sbios_requests
  8. radeon_atif_handler
  9. radeon_atcs_call
  10. radeon_atcs_parse_functions
  11. radeon_atcs_verify_interface
  12. radeon_acpi_is_pcie_performance_request_supported
  13. radeon_acpi_pcie_notify_device_ready
  14. radeon_acpi_pcie_performance_request
  15. radeon_acpi_event
  16. radeon_acpi_init
  17. radeon_acpi_fini

   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)
  41 bool radeon_atpx_dgpu_req_power_for_displays(void);
  42 #else
  43 static inline bool radeon_atpx_dgpu_req_power_for_displays(void) { return false; }
  44 #endif
  45 
  46 #define ACPI_AC_CLASS           "ac_adapter"
  47 
  48 extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev);
  49 
  50 struct 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 
  57 struct 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 
  64 struct 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 
  81 struct 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 
  89 struct 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 
  98 struct 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  */
 115 static 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  */
 162 static 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  */
 185 static 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  */
 210 static 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 
 240 out:
 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  */
 257 static 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 
 300 out:
 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  */
 319 static 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 
 343 out:
 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  */
 358 static 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  */
 440 static 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  */
 487 static 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  */
 506 static 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 
 535 out:
 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  */
 549 bool 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  */
 568 int 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  */
 602 int 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  */
 680 static 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  */
 710 int 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 
 786 out:
 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  */
 800 void radeon_acpi_fini(struct radeon_device *rdev)
 801 {
 802         unregister_acpi_notifier(&rdev->acpi_nb);
 803 }

/* [<][>][^][v][top][bottom][index][help] */