0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/vga_switcheroo.h>
0009 #include <linux/slab.h>
0010 #include <linux/acpi.h>
0011 #include <linux/pci.h>
0012 #include <linux/delay.h>
0013
0014 #include "amdgpu.h"
0015 #include "amd_acpi.h"
0016
0017 #define AMDGPU_PX_QUIRK_FORCE_ATPX (1 << 0)
0018
0019 struct amdgpu_px_quirk {
0020 u32 chip_vendor;
0021 u32 chip_device;
0022 u32 subsys_vendor;
0023 u32 subsys_device;
0024 u32 px_quirk_flags;
0025 };
0026
0027 struct amdgpu_atpx_functions {
0028 bool px_params;
0029 bool power_cntl;
0030 bool disp_mux_cntl;
0031 bool i2c_mux_cntl;
0032 bool switch_start;
0033 bool switch_end;
0034 bool disp_connectors_mapping;
0035 bool disp_detection_ports;
0036 };
0037
0038 struct amdgpu_atpx {
0039 acpi_handle handle;
0040 struct amdgpu_atpx_functions functions;
0041 bool is_hybrid;
0042 bool dgpu_req_power_for_displays;
0043 };
0044
0045 static struct amdgpu_atpx_priv {
0046 bool atpx_detected;
0047 bool bridge_pm_usable;
0048 unsigned int quirks;
0049
0050 acpi_handle dhandle;
0051 acpi_handle other_handle;
0052 struct amdgpu_atpx atpx;
0053 } amdgpu_atpx_priv;
0054
0055 struct atpx_verify_interface {
0056 u16 size;
0057 u16 version;
0058 u32 function_bits;
0059 } __packed;
0060
0061 struct atpx_px_params {
0062 u16 size;
0063 u32 valid_flags;
0064 u32 flags;
0065 } __packed;
0066
0067 struct atpx_power_control {
0068 u16 size;
0069 u8 dgpu_state;
0070 } __packed;
0071
0072 struct atpx_mux {
0073 u16 size;
0074 u16 mux;
0075 } __packed;
0076
0077 bool amdgpu_has_atpx(void) {
0078 return amdgpu_atpx_priv.atpx_detected;
0079 }
0080
0081 bool amdgpu_has_atpx_dgpu_power_cntl(void) {
0082 return amdgpu_atpx_priv.atpx.functions.power_cntl;
0083 }
0084
0085 bool amdgpu_is_atpx_hybrid(void) {
0086 return amdgpu_atpx_priv.atpx.is_hybrid;
0087 }
0088
0089 bool amdgpu_atpx_dgpu_req_power_for_displays(void) {
0090 return amdgpu_atpx_priv.atpx.dgpu_req_power_for_displays;
0091 }
0092
0093 #if defined(CONFIG_ACPI)
0094 void *amdgpu_atpx_get_dhandle(void) {
0095 return amdgpu_atpx_priv.dhandle;
0096 }
0097 #endif
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 static union acpi_object *amdgpu_atpx_call(acpi_handle handle, int function,
0110 struct acpi_buffer *params)
0111 {
0112 acpi_status status;
0113 union acpi_object atpx_arg_elements[2];
0114 struct acpi_object_list atpx_arg;
0115 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0116
0117 atpx_arg.count = 2;
0118 atpx_arg.pointer = &atpx_arg_elements[0];
0119
0120 atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
0121 atpx_arg_elements[0].integer.value = function;
0122
0123 if (params) {
0124 atpx_arg_elements[1].type = ACPI_TYPE_BUFFER;
0125 atpx_arg_elements[1].buffer.length = params->length;
0126 atpx_arg_elements[1].buffer.pointer = params->pointer;
0127 } else {
0128
0129 atpx_arg_elements[1].type = ACPI_TYPE_INTEGER;
0130 atpx_arg_elements[1].integer.value = 0;
0131 }
0132
0133 status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
0134
0135
0136 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
0137 printk("failed to evaluate ATPX got %s\n",
0138 acpi_format_exception(status));
0139 kfree(buffer.pointer);
0140 return NULL;
0141 }
0142
0143 return buffer.pointer;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mask)
0157 {
0158 f->px_params = mask & ATPX_GET_PX_PARAMETERS_SUPPORTED;
0159 f->power_cntl = mask & ATPX_POWER_CONTROL_SUPPORTED;
0160 f->disp_mux_cntl = mask & ATPX_DISPLAY_MUX_CONTROL_SUPPORTED;
0161 f->i2c_mux_cntl = mask & ATPX_I2C_MUX_CONTROL_SUPPORTED;
0162 f->switch_start = mask & ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED;
0163 f->switch_end = mask & ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED;
0164 f->disp_connectors_mapping = mask & ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED;
0165 f->disp_detection_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED;
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
0177 {
0178 u32 valid_bits = 0;
0179
0180 if (atpx->functions.px_params) {
0181 union acpi_object *info;
0182 struct atpx_px_params output;
0183 size_t size;
0184
0185 info = amdgpu_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
0186 if (!info)
0187 return -EIO;
0188
0189 memset(&output, 0, sizeof(output));
0190
0191 size = *(u16 *) info->buffer.pointer;
0192 if (size < 10) {
0193 printk("ATPX buffer is too small: %zu\n", size);
0194 kfree(info);
0195 return -EINVAL;
0196 }
0197 size = min(sizeof(output), size);
0198
0199 memcpy(&output, info->buffer.pointer, size);
0200
0201 valid_bits = output.flags & output.valid_flags;
0202
0203 kfree(info);
0204 }
0205
0206
0207 if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) {
0208 atpx->functions.i2c_mux_cntl = true;
0209 atpx->functions.disp_mux_cntl = true;
0210 }
0211
0212 if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED |
0213 ATPX_TV_SIGNAL_MUXED |
0214 ATPX_DFP_SIGNAL_MUXED))
0215 atpx->functions.disp_mux_cntl = true;
0216
0217
0218
0219 if (valid_bits & (ATPX_DYNAMIC_PX_SUPPORTED |
0220 ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED))
0221 atpx->functions.power_cntl = true;
0222
0223 atpx->is_hybrid = false;
0224 if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
0225 if (amdgpu_atpx_priv.quirks & AMDGPU_PX_QUIRK_FORCE_ATPX) {
0226 printk("ATPX Hybrid Graphics, forcing to ATPX\n");
0227 atpx->functions.power_cntl = true;
0228 atpx->is_hybrid = false;
0229 } else {
0230 printk("ATPX Hybrid Graphics\n");
0231
0232
0233
0234
0235 atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable;
0236 atpx->is_hybrid = true;
0237 }
0238 }
0239
0240 atpx->dgpu_req_power_for_displays = false;
0241 if (valid_bits & ATPX_DGPU_REQ_POWER_FOR_DISPLAYS)
0242 atpx->dgpu_req_power_for_displays = true;
0243
0244 return 0;
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 static int amdgpu_atpx_verify_interface(struct amdgpu_atpx *atpx)
0258 {
0259 union acpi_object *info;
0260 struct atpx_verify_interface output;
0261 size_t size;
0262 int err = 0;
0263
0264 info = amdgpu_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE, NULL);
0265 if (!info)
0266 return -EIO;
0267
0268 memset(&output, 0, sizeof(output));
0269
0270 size = *(u16 *) info->buffer.pointer;
0271 if (size < 8) {
0272 printk("ATPX buffer is too small: %zu\n", size);
0273 err = -EINVAL;
0274 goto out;
0275 }
0276 size = min(sizeof(output), size);
0277
0278 memcpy(&output, info->buffer.pointer, size);
0279
0280
0281 printk("ATPX version %u, functions 0x%08x\n",
0282 output.version, output.function_bits);
0283
0284 amdgpu_atpx_parse_functions(&atpx->functions, output.function_bits);
0285
0286 out:
0287 kfree(info);
0288 return err;
0289 }
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 static int amdgpu_atpx_set_discrete_state(struct amdgpu_atpx *atpx, u8 state)
0302 {
0303 struct acpi_buffer params;
0304 union acpi_object *info;
0305 struct atpx_power_control input;
0306
0307 if (atpx->functions.power_cntl) {
0308 input.size = 3;
0309 input.dgpu_state = state;
0310 params.length = input.size;
0311 params.pointer = &input;
0312 info = amdgpu_atpx_call(atpx->handle,
0313 ATPX_FUNCTION_POWER_CONTROL,
0314 ¶ms);
0315 if (!info)
0316 return -EIO;
0317 kfree(info);
0318
0319
0320 if (state == 0)
0321 msleep(200);
0322 }
0323 return 0;
0324 }
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 static int amdgpu_atpx_switch_disp_mux(struct amdgpu_atpx *atpx, u16 mux_id)
0338 {
0339 struct acpi_buffer params;
0340 union acpi_object *info;
0341 struct atpx_mux input;
0342
0343 if (atpx->functions.disp_mux_cntl) {
0344 input.size = 4;
0345 input.mux = mux_id;
0346 params.length = input.size;
0347 params.pointer = &input;
0348 info = amdgpu_atpx_call(atpx->handle,
0349 ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
0350 ¶ms);
0351 if (!info)
0352 return -EIO;
0353 kfree(info);
0354 }
0355 return 0;
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369 static int amdgpu_atpx_switch_i2c_mux(struct amdgpu_atpx *atpx, u16 mux_id)
0370 {
0371 struct acpi_buffer params;
0372 union acpi_object *info;
0373 struct atpx_mux input;
0374
0375 if (atpx->functions.i2c_mux_cntl) {
0376 input.size = 4;
0377 input.mux = mux_id;
0378 params.length = input.size;
0379 params.pointer = &input;
0380 info = amdgpu_atpx_call(atpx->handle,
0381 ATPX_FUNCTION_I2C_MUX_CONTROL,
0382 ¶ms);
0383 if (!info)
0384 return -EIO;
0385 kfree(info);
0386 }
0387 return 0;
0388 }
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401 static int amdgpu_atpx_switch_start(struct amdgpu_atpx *atpx, u16 mux_id)
0402 {
0403 struct acpi_buffer params;
0404 union acpi_object *info;
0405 struct atpx_mux input;
0406
0407 if (atpx->functions.switch_start) {
0408 input.size = 4;
0409 input.mux = mux_id;
0410 params.length = input.size;
0411 params.pointer = &input;
0412 info = amdgpu_atpx_call(atpx->handle,
0413 ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
0414 ¶ms);
0415 if (!info)
0416 return -EIO;
0417 kfree(info);
0418 }
0419 return 0;
0420 }
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 static int amdgpu_atpx_switch_end(struct amdgpu_atpx *atpx, u16 mux_id)
0434 {
0435 struct acpi_buffer params;
0436 union acpi_object *info;
0437 struct atpx_mux input;
0438
0439 if (atpx->functions.switch_end) {
0440 input.size = 4;
0441 input.mux = mux_id;
0442 params.length = input.size;
0443 params.pointer = &input;
0444 info = amdgpu_atpx_call(atpx->handle,
0445 ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
0446 ¶ms);
0447 if (!info)
0448 return -EIO;
0449 kfree(info);
0450 }
0451 return 0;
0452 }
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463 static int amdgpu_atpx_switchto(enum vga_switcheroo_client_id id)
0464 {
0465 u16 gpu_id;
0466
0467 if (id == VGA_SWITCHEROO_IGD)
0468 gpu_id = ATPX_INTEGRATED_GPU;
0469 else
0470 gpu_id = ATPX_DISCRETE_GPU;
0471
0472 amdgpu_atpx_switch_start(&amdgpu_atpx_priv.atpx, gpu_id);
0473 amdgpu_atpx_switch_disp_mux(&amdgpu_atpx_priv.atpx, gpu_id);
0474 amdgpu_atpx_switch_i2c_mux(&amdgpu_atpx_priv.atpx, gpu_id);
0475 amdgpu_atpx_switch_end(&amdgpu_atpx_priv.atpx, gpu_id);
0476
0477 return 0;
0478 }
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490 static int amdgpu_atpx_power_state(enum vga_switcheroo_client_id id,
0491 enum vga_switcheroo_state state)
0492 {
0493
0494 if (id == VGA_SWITCHEROO_IGD)
0495 return 0;
0496
0497 amdgpu_atpx_set_discrete_state(&amdgpu_atpx_priv.atpx, state);
0498 return 0;
0499 }
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509 static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)
0510 {
0511 acpi_handle dhandle, atpx_handle;
0512 acpi_status status;
0513
0514 dhandle = ACPI_HANDLE(&pdev->dev);
0515 if (!dhandle)
0516 return false;
0517
0518 status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
0519 if (ACPI_FAILURE(status)) {
0520 amdgpu_atpx_priv.other_handle = dhandle;
0521 return false;
0522 }
0523 amdgpu_atpx_priv.dhandle = dhandle;
0524 amdgpu_atpx_priv.atpx.handle = atpx_handle;
0525 return true;
0526 }
0527
0528
0529
0530
0531
0532
0533
0534 static int amdgpu_atpx_init(void)
0535 {
0536 int r;
0537
0538
0539 r = amdgpu_atpx_verify_interface(&amdgpu_atpx_priv.atpx);
0540 if (r)
0541 return r;
0542
0543
0544 r = amdgpu_atpx_validate(&amdgpu_atpx_priv.atpx);
0545 if (r)
0546 return r;
0547
0548 return 0;
0549 }
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559 static enum vga_switcheroo_client_id amdgpu_atpx_get_client_id(struct pci_dev *pdev)
0560 {
0561 if (amdgpu_atpx_priv.dhandle == ACPI_HANDLE(&pdev->dev))
0562 return VGA_SWITCHEROO_IGD;
0563 else
0564 return VGA_SWITCHEROO_DIS;
0565 }
0566
0567 static const struct vga_switcheroo_handler amdgpu_atpx_handler = {
0568 .switchto = amdgpu_atpx_switchto,
0569 .power_state = amdgpu_atpx_power_state,
0570 .get_client_id = amdgpu_atpx_get_client_id,
0571 };
0572
0573 static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
0574
0575 { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },
0576 { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
0577 { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX },
0578 { 0x1002, 0x699f, 0x1028, 0x0814, AMDGPU_PX_QUIRK_FORCE_ATPX },
0579 { 0x1002, 0x6900, 0x1025, 0x125A, AMDGPU_PX_QUIRK_FORCE_ATPX },
0580 { 0x1002, 0x6900, 0x17AA, 0x3806, AMDGPU_PX_QUIRK_FORCE_ATPX },
0581 { 0, 0, 0, 0, 0 },
0582 };
0583
0584 static void amdgpu_atpx_get_quirks(struct pci_dev *pdev)
0585 {
0586 const struct amdgpu_px_quirk *p = amdgpu_px_quirk_list;
0587
0588
0589 while (p && p->chip_device != 0) {
0590 if (pdev->vendor == p->chip_vendor &&
0591 pdev->device == p->chip_device &&
0592 pdev->subsystem_vendor == p->subsys_vendor &&
0593 pdev->subsystem_device == p->subsys_device) {
0594 amdgpu_atpx_priv.quirks |= p->px_quirk_flags;
0595 break;
0596 }
0597 ++p;
0598 }
0599 }
0600
0601
0602
0603
0604
0605
0606
0607 static bool amdgpu_atpx_detect(void)
0608 {
0609 char acpi_method_name[255] = { 0 };
0610 struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
0611 struct pci_dev *pdev = NULL;
0612 bool has_atpx = false;
0613 int vga_count = 0;
0614 bool d3_supported = false;
0615 struct pci_dev *parent_pdev;
0616
0617 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
0618 vga_count++;
0619
0620 has_atpx |= amdgpu_atpx_pci_probe_handle(pdev);
0621
0622 parent_pdev = pci_upstream_bridge(pdev);
0623 d3_supported |= parent_pdev && parent_pdev->bridge_d3;
0624 amdgpu_atpx_get_quirks(pdev);
0625 }
0626
0627 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
0628 vga_count++;
0629
0630 has_atpx |= amdgpu_atpx_pci_probe_handle(pdev);
0631
0632 parent_pdev = pci_upstream_bridge(pdev);
0633 d3_supported |= parent_pdev && parent_pdev->bridge_d3;
0634 amdgpu_atpx_get_quirks(pdev);
0635 }
0636
0637 if (has_atpx && vga_count == 2) {
0638 acpi_get_name(amdgpu_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
0639 pr_info("vga_switcheroo: detected switching method %s handle\n",
0640 acpi_method_name);
0641 amdgpu_atpx_priv.atpx_detected = true;
0642 amdgpu_atpx_priv.bridge_pm_usable = d3_supported;
0643 amdgpu_atpx_init();
0644 return true;
0645 }
0646 return false;
0647 }
0648
0649
0650
0651
0652
0653
0654 void amdgpu_register_atpx_handler(void)
0655 {
0656 bool r;
0657 enum vga_switcheroo_handler_flags_t handler_flags = 0;
0658
0659
0660 r = amdgpu_atpx_detect();
0661 if (!r)
0662 return;
0663
0664 vga_switcheroo_register_handler(&amdgpu_atpx_handler, handler_flags);
0665 }
0666
0667
0668
0669
0670
0671
0672 void amdgpu_unregister_atpx_handler(void)
0673 {
0674 vga_switcheroo_unregister_handler();
0675 }