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