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