1 /* 2 * Copyright (c) 2010 Red Hat Inc. 3 * Author : Dave Airlie <airlied@redhat.com> 4 * 5 * Licensed under GPLv2 6 * 7 * ATPX support for both Intel/ATI 8 */ 9 #include <linux/vga_switcheroo.h> 10 #include <linux/slab.h> 11 #include <linux/acpi.h> 12 #include <linux/pci.h> 13 #include <linux/delay.h> 14 15 #include "radeon_acpi.h" 16 17 struct radeon_atpx_functions { 18 bool px_params; 19 bool power_cntl; 20 bool disp_mux_cntl; 21 bool i2c_mux_cntl; 22 bool switch_start; 23 bool switch_end; 24 bool disp_connectors_mapping; 25 bool disp_detetion_ports; 26 }; 27 28 struct radeon_atpx { 29 acpi_handle handle; 30 struct radeon_atpx_functions functions; 31 bool is_hybrid; 32 bool dgpu_req_power_for_displays; 33 }; 34 35 static struct radeon_atpx_priv { 36 bool atpx_detected; 37 bool bridge_pm_usable; 38 /* handle for device - and atpx */ 39 acpi_handle dhandle; 40 struct radeon_atpx atpx; 41 } radeon_atpx_priv; 42 43 struct atpx_verify_interface { 44 u16 size; /* structure size in bytes (includes size field) */ 45 u16 version; /* version */ 46 u32 function_bits; /* supported functions bit vector */ 47 } __packed; 48 49 struct atpx_px_params { 50 u16 size; /* structure size in bytes (includes size field) */ 51 u32 valid_flags; /* which flags are valid */ 52 u32 flags; /* flags */ 53 } __packed; 54 55 struct atpx_power_control { 56 u16 size; 57 u8 dgpu_state; 58 } __packed; 59 60 struct atpx_mux { 61 u16 size; 62 u16 mux; 63 } __packed; 64 65 bool radeon_has_atpx(void) { 66 return radeon_atpx_priv.atpx_detected; 67 } 68 69 bool radeon_has_atpx_dgpu_power_cntl(void) { 70 return radeon_atpx_priv.atpx.functions.power_cntl; 71 } 72 73 bool radeon_is_atpx_hybrid(void) { 74 return radeon_atpx_priv.atpx.is_hybrid; 75 } 76 77 bool radeon_atpx_dgpu_req_power_for_displays(void) { 78 return radeon_atpx_priv.atpx.dgpu_req_power_for_displays; 79 } 80 81 /** 82 * radeon_atpx_call - call an ATPX method 83 * 84 * @handle: acpi handle 85 * @function: the ATPX function to execute 86 * @params: ATPX function params 87 * 88 * Executes the requested ATPX function (all asics). 89 * Returns a pointer to the acpi output buffer. 90 */ 91 static union acpi_object *radeon_atpx_call(acpi_handle handle, int function, 92 struct acpi_buffer *params) 93 { 94 acpi_status status; 95 union acpi_object atpx_arg_elements[2]; 96 struct acpi_object_list atpx_arg; 97 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 98 99 atpx_arg.count = 2; 100 atpx_arg.pointer = &atpx_arg_elements[0]; 101 102 atpx_arg_elements[0].type = ACPI_TYPE_INTEGER; 103 atpx_arg_elements[0].integer.value = function; 104 105 if (params) { 106 atpx_arg_elements[1].type = ACPI_TYPE_BUFFER; 107 atpx_arg_elements[1].buffer.length = params->length; 108 atpx_arg_elements[1].buffer.pointer = params->pointer; 109 } else { 110 /* We need a second fake parameter */ 111 atpx_arg_elements[1].type = ACPI_TYPE_INTEGER; 112 atpx_arg_elements[1].integer.value = 0; 113 } 114 115 status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); 116 117 /* Fail only if calling the method fails and ATPX is supported */ 118 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 119 printk("failed to evaluate ATPX got %s\n", 120 acpi_format_exception(status)); 121 kfree(buffer.pointer); 122 return NULL; 123 } 124 125 return buffer.pointer; 126 } 127 128 /** 129 * radeon_atpx_parse_functions - parse supported functions 130 * 131 * @f: supported functions struct 132 * @mask: supported functions mask from ATPX 133 * 134 * Use the supported functions mask from ATPX function 135 * ATPX_FUNCTION_VERIFY_INTERFACE to determine what functions 136 * are supported (all asics). 137 */ 138 static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mask) 139 { 140 f->px_params = mask & ATPX_GET_PX_PARAMETERS_SUPPORTED; 141 f->power_cntl = mask & ATPX_POWER_CONTROL_SUPPORTED; 142 f->disp_mux_cntl = mask & ATPX_DISPLAY_MUX_CONTROL_SUPPORTED; 143 f->i2c_mux_cntl = mask & ATPX_I2C_MUX_CONTROL_SUPPORTED; 144 f->switch_start = mask & ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED; 145 f->switch_end = mask & ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED; 146 f->disp_connectors_mapping = mask & ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED; 147 f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED; 148 } 149 150 /** 151 * radeon_atpx_validate_functions - validate ATPX functions 152 * 153 * @atpx: radeon atpx struct 154 * 155 * Validate that required functions are enabled (all asics). 156 * returns 0 on success, error on failure. 157 */ 158 static int radeon_atpx_validate(struct radeon_atpx *atpx) 159 { 160 u32 valid_bits = 0; 161 162 if (atpx->functions.px_params) { 163 union acpi_object *info; 164 struct atpx_px_params output; 165 size_t size; 166 167 info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); 168 if (!info) 169 return -EIO; 170 171 memset(&output, 0, sizeof(output)); 172 173 size = *(u16 *) info->buffer.pointer; 174 if (size < 10) { 175 printk("ATPX buffer is too small: %zu\n", size); 176 kfree(info); 177 return -EINVAL; 178 } 179 size = min(sizeof(output), size); 180 181 memcpy(&output, info->buffer.pointer, size); 182 183 valid_bits = output.flags & output.valid_flags; 184 185 kfree(info); 186 } 187 188 /* if separate mux flag is set, mux controls are required */ 189 if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { 190 atpx->functions.i2c_mux_cntl = true; 191 atpx->functions.disp_mux_cntl = true; 192 } 193 /* if any outputs are muxed, mux controls are required */ 194 if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | 195 ATPX_TV_SIGNAL_MUXED | 196 ATPX_DFP_SIGNAL_MUXED)) 197 atpx->functions.disp_mux_cntl = true; 198 199 /* some bioses set these bits rather than flagging power_cntl as supported */ 200 if (valid_bits & (ATPX_DYNAMIC_PX_SUPPORTED | 201 ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED)) 202 atpx->functions.power_cntl = true; 203 204 atpx->is_hybrid = false; 205 if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { 206 printk("ATPX Hybrid Graphics\n"); 207 /* 208 * Disable legacy PM methods only when pcie port PM is usable, 209 * otherwise the device might fail to power off or power on. 210 */ 211 atpx->functions.power_cntl = !radeon_atpx_priv.bridge_pm_usable; 212 atpx->is_hybrid = true; 213 } 214 215 return 0; 216 } 217 218 /** 219 * radeon_atpx_verify_interface - verify ATPX 220 * 221 * @atpx: radeon atpx struct 222 * 223 * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function 224 * to initialize ATPX and determine what features are supported 225 * (all asics). 226 * returns 0 on success, error on failure. 227 */ 228 static int radeon_atpx_verify_interface(struct radeon_atpx *atpx) 229 { 230 union acpi_object *info; 231 struct atpx_verify_interface output; 232 size_t size; 233 int err = 0; 234 235 info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE, NULL); 236 if (!info) 237 return -EIO; 238 239 memset(&output, 0, sizeof(output)); 240 241 size = *(u16 *) info->buffer.pointer; 242 if (size < 8) { 243 printk("ATPX buffer is too small: %zu\n", size); 244 err = -EINVAL; 245 goto out; 246 } 247 size = min(sizeof(output), size); 248 249 memcpy(&output, info->buffer.pointer, size); 250 251 /* TODO: check version? */ 252 printk("ATPX version %u, functions 0x%08x\n", 253 output.version, output.function_bits); 254 255 radeon_atpx_parse_functions(&atpx->functions, output.function_bits); 256 257 out: 258 kfree(info); 259 return err; 260 } 261 262 /** 263 * radeon_atpx_set_discrete_state - power up/down discrete GPU 264 * 265 * @atpx: atpx info struct 266 * @state: discrete GPU state (0 = power down, 1 = power up) 267 * 268 * Execute the ATPX_FUNCTION_POWER_CONTROL ATPX function to 269 * power down/up the discrete GPU (all asics). 270 * Returns 0 on success, error on failure. 271 */ 272 static int radeon_atpx_set_discrete_state(struct radeon_atpx *atpx, u8 state) 273 { 274 struct acpi_buffer params; 275 union acpi_object *info; 276 struct atpx_power_control input; 277 278 if (atpx->functions.power_cntl) { 279 input.size = 3; 280 input.dgpu_state = state; 281 params.length = input.size; 282 params.pointer = &input; 283 info = radeon_atpx_call(atpx->handle, 284 ATPX_FUNCTION_POWER_CONTROL, 285 ¶ms); 286 if (!info) 287 return -EIO; 288 kfree(info); 289 290 /* 200ms delay is required after off */ 291 if (state == 0) 292 msleep(200); 293 } 294 return 0; 295 } 296 297 /** 298 * radeon_atpx_switch_disp_mux - switch display mux 299 * 300 * @atpx: atpx info struct 301 * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU) 302 * 303 * Execute the ATPX_FUNCTION_DISPLAY_MUX_CONTROL ATPX function to 304 * switch the display mux between the discrete GPU and integrated GPU 305 * (all asics). 306 * Returns 0 on success, error on failure. 307 */ 308 static int radeon_atpx_switch_disp_mux(struct radeon_atpx *atpx, u16 mux_id) 309 { 310 struct acpi_buffer params; 311 union acpi_object *info; 312 struct atpx_mux input; 313 314 if (atpx->functions.disp_mux_cntl) { 315 input.size = 4; 316 input.mux = mux_id; 317 params.length = input.size; 318 params.pointer = &input; 319 info = radeon_atpx_call(atpx->handle, 320 ATPX_FUNCTION_DISPLAY_MUX_CONTROL, 321 ¶ms); 322 if (!info) 323 return -EIO; 324 kfree(info); 325 } 326 return 0; 327 } 328 329 /** 330 * radeon_atpx_switch_i2c_mux - switch i2c/hpd mux 331 * 332 * @atpx: atpx info struct 333 * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU) 334 * 335 * Execute the ATPX_FUNCTION_I2C_MUX_CONTROL ATPX function to 336 * switch the i2c/hpd mux between the discrete GPU and integrated GPU 337 * (all asics). 338 * Returns 0 on success, error on failure. 339 */ 340 static int radeon_atpx_switch_i2c_mux(struct radeon_atpx *atpx, u16 mux_id) 341 { 342 struct acpi_buffer params; 343 union acpi_object *info; 344 struct atpx_mux input; 345 346 if (atpx->functions.i2c_mux_cntl) { 347 input.size = 4; 348 input.mux = mux_id; 349 params.length = input.size; 350 params.pointer = &input; 351 info = radeon_atpx_call(atpx->handle, 352 ATPX_FUNCTION_I2C_MUX_CONTROL, 353 ¶ms); 354 if (!info) 355 return -EIO; 356 kfree(info); 357 } 358 return 0; 359 } 360 361 /** 362 * radeon_atpx_switch_start - notify the sbios of a GPU switch 363 * 364 * @atpx: atpx info struct 365 * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU) 366 * 367 * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION ATPX 368 * function to notify the sbios that a switch between the discrete GPU and 369 * integrated GPU has begun (all asics). 370 * Returns 0 on success, error on failure. 371 */ 372 static int radeon_atpx_switch_start(struct radeon_atpx *atpx, u16 mux_id) 373 { 374 struct acpi_buffer params; 375 union acpi_object *info; 376 struct atpx_mux input; 377 378 if (atpx->functions.switch_start) { 379 input.size = 4; 380 input.mux = mux_id; 381 params.length = input.size; 382 params.pointer = &input; 383 info = radeon_atpx_call(atpx->handle, 384 ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION, 385 ¶ms); 386 if (!info) 387 return -EIO; 388 kfree(info); 389 } 390 return 0; 391 } 392 393 /** 394 * radeon_atpx_switch_end - notify the sbios of a GPU switch 395 * 396 * @atpx: atpx info struct 397 * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU) 398 * 399 * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION ATPX 400 * function to notify the sbios that a switch between the discrete GPU and 401 * integrated GPU has ended (all asics). 402 * Returns 0 on success, error on failure. 403 */ 404 static int radeon_atpx_switch_end(struct radeon_atpx *atpx, u16 mux_id) 405 { 406 struct acpi_buffer params; 407 union acpi_object *info; 408 struct atpx_mux input; 409 410 if (atpx->functions.switch_end) { 411 input.size = 4; 412 input.mux = mux_id; 413 params.length = input.size; 414 params.pointer = &input; 415 info = radeon_atpx_call(atpx->handle, 416 ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION, 417 ¶ms); 418 if (!info) 419 return -EIO; 420 kfree(info); 421 } 422 return 0; 423 } 424 425 /** 426 * radeon_atpx_switchto - switch to the requested GPU 427 * 428 * @id: GPU to switch to 429 * 430 * Execute the necessary ATPX functions to switch between the discrete GPU and 431 * integrated GPU (all asics). 432 * Returns 0 on success, error on failure. 433 */ 434 static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) 435 { 436 u16 gpu_id; 437 438 if (id == VGA_SWITCHEROO_IGD) 439 gpu_id = ATPX_INTEGRATED_GPU; 440 else 441 gpu_id = ATPX_DISCRETE_GPU; 442 443 radeon_atpx_switch_start(&radeon_atpx_priv.atpx, gpu_id); 444 radeon_atpx_switch_disp_mux(&radeon_atpx_priv.atpx, gpu_id); 445 radeon_atpx_switch_i2c_mux(&radeon_atpx_priv.atpx, gpu_id); 446 radeon_atpx_switch_end(&radeon_atpx_priv.atpx, gpu_id); 447 448 return 0; 449 } 450 451 /** 452 * radeon_atpx_power_state - power down/up the requested GPU 453 * 454 * @id: GPU to power down/up 455 * @state: requested power state (0 = off, 1 = on) 456 * 457 * Execute the necessary ATPX function to power down/up the discrete GPU 458 * (all asics). 459 * Returns 0 on success, error on failure. 460 */ 461 static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, 462 enum vga_switcheroo_state state) 463 { 464 /* on w500 ACPI can't change intel gpu state */ 465 if (id == VGA_SWITCHEROO_IGD) 466 return 0; 467 468 radeon_atpx_set_discrete_state(&radeon_atpx_priv.atpx, state); 469 return 0; 470 } 471 472 /** 473 * radeon_atpx_pci_probe_handle - look up the ATPX handle 474 * 475 * @pdev: pci device 476 * 477 * Look up the ATPX handles (all asics). 478 * Returns true if the handles are found, false if not. 479 */ 480 static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) 481 { 482 acpi_handle dhandle, atpx_handle; 483 acpi_status status; 484 485 dhandle = ACPI_HANDLE(&pdev->dev); 486 if (!dhandle) 487 return false; 488 489 status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); 490 if (ACPI_FAILURE(status)) 491 return false; 492 493 radeon_atpx_priv.dhandle = dhandle; 494 radeon_atpx_priv.atpx.handle = atpx_handle; 495 return true; 496 } 497 498 /** 499 * radeon_atpx_init - verify the ATPX interface 500 * 501 * Verify the ATPX interface (all asics). 502 * Returns 0 on success, error on failure. 503 */ 504 static int radeon_atpx_init(void) 505 { 506 int r; 507 508 /* set up the ATPX handle */ 509 r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); 510 if (r) 511 return r; 512 513 /* validate the atpx setup */ 514 r = radeon_atpx_validate(&radeon_atpx_priv.atpx); 515 if (r) 516 return r; 517 518 return 0; 519 } 520 521 /** 522 * radeon_atpx_get_client_id - get the client id 523 * 524 * @pdev: pci device 525 * 526 * look up whether we are the integrated or discrete GPU (all asics). 527 * Returns the client id. 528 */ 529 static enum vga_switcheroo_client_id radeon_atpx_get_client_id(struct pci_dev *pdev) 530 { 531 if (radeon_atpx_priv.dhandle == ACPI_HANDLE(&pdev->dev)) 532 return VGA_SWITCHEROO_IGD; 533 else 534 return VGA_SWITCHEROO_DIS; 535 } 536 537 static const struct vga_switcheroo_handler radeon_atpx_handler = { 538 .switchto = radeon_atpx_switchto, 539 .power_state = radeon_atpx_power_state, 540 .get_client_id = radeon_atpx_get_client_id, 541 }; 542 543 /** 544 * radeon_atpx_detect - detect whether we have PX 545 * 546 * Check if we have a PX system (all asics). 547 * Returns true if we have a PX system, false if not. 548 */ 549 static bool radeon_atpx_detect(void) 550 { 551 char acpi_method_name[255] = { 0 }; 552 struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; 553 struct pci_dev *pdev = NULL; 554 bool has_atpx = false; 555 int vga_count = 0; 556 bool d3_supported = false; 557 struct pci_dev *parent_pdev; 558 559 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { 560 vga_count++; 561 562 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true); 563 564 parent_pdev = pci_upstream_bridge(pdev); 565 d3_supported |= parent_pdev && parent_pdev->bridge_d3; 566 } 567 568 /* some newer PX laptops mark the dGPU as a non-VGA display device */ 569 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { 570 vga_count++; 571 572 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true); 573 574 parent_pdev = pci_upstream_bridge(pdev); 575 d3_supported |= parent_pdev && parent_pdev->bridge_d3; 576 } 577 578 if (has_atpx && vga_count == 2) { 579 acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer); 580 pr_info("vga_switcheroo: detected switching method %s handle\n", 581 acpi_method_name); 582 radeon_atpx_priv.atpx_detected = true; 583 radeon_atpx_priv.bridge_pm_usable = d3_supported; 584 radeon_atpx_init(); 585 return true; 586 } 587 return false; 588 } 589 590 /** 591 * radeon_register_atpx_handler - register with vga_switcheroo 592 * 593 * Register the PX callbacks with vga_switcheroo (all asics). 594 */ 595 void radeon_register_atpx_handler(void) 596 { 597 bool r; 598 enum vga_switcheroo_handler_flags_t handler_flags = 0; 599 600 /* detect if we have any ATPX + 2 VGA in the system */ 601 r = radeon_atpx_detect(); 602 if (!r) 603 return; 604 605 vga_switcheroo_register_handler(&radeon_atpx_handler, handler_flags); 606 } 607 608 /** 609 * radeon_unregister_atpx_handler - unregister with vga_switcheroo 610 * 611 * Unregister the PX callbacks with vga_switcheroo (all asics). 612 */ 613 void radeon_unregister_atpx_handler(void) 614 { 615 vga_switcheroo_unregister_handler(); 616 } 617