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