Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: support atcs method powershift (v4)

add support to handle ATCS method for power shift control.
used to communicate dGPU device state to SBIOS.

V2: use defined acpi func for checking psc support (Lijo)
fix alignment (Shashank)
V3: rebased on unified ATCS handling (Alex)
V4: rebased on ATPX/ATCS structures global (Alex)

Signed-off-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Sathishkumar S and committed by
Alex Deucher
16eb48c6 8a81028b

+79
+6
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 1340 1340 int amdgpu_acpi_init(struct amdgpu_device *adev); 1341 1341 void amdgpu_acpi_fini(struct amdgpu_device *adev); 1342 1342 bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev); 1343 + bool amdgpu_acpi_is_power_shift_control_supported(void); 1343 1344 int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, 1344 1345 u8 perf_req, bool advertise); 1346 + int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, 1347 + u8 dev_state, bool drv_state); 1345 1348 int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev); 1346 1349 1347 1350 void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps); ··· 1355 1352 static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { } 1356 1353 static inline bool amdgpu_acpi_is_s0ix_supported(struct amdgpu_device *adev) { return false; } 1357 1354 static inline void amdgpu_acpi_detect(void) { } 1355 + static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; } 1356 + static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, 1357 + u8 dev_state, bool drv_state) { return 0; } 1358 1358 #endif 1359 1359 1360 1360 int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
+55
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
··· 76 76 bool pcie_perf_req; 77 77 bool pcie_dev_rdy; 78 78 bool pcie_bus_width; 79 + bool power_shift_control; 79 80 }; 80 81 81 82 struct amdgpu_atcs { ··· 535 534 f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED; 536 535 f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED; 537 536 f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED; 537 + f->power_shift_control = mask & ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED; 538 538 } 539 539 540 540 /** ··· 598 596 return true; 599 597 600 598 return false; 599 + } 600 + 601 + /** 602 + * amdgpu_acpi_is_power_shift_control_supported 603 + * 604 + * Check if the ATCS power shift control method 605 + * is supported. 606 + * returns true if supported, false if not. 607 + */ 608 + bool amdgpu_acpi_is_power_shift_control_supported(void) 609 + { 610 + return amdgpu_acpi_priv.atcs.functions.power_shift_control; 601 611 } 602 612 603 613 /** ··· 708 694 udelay(10); 709 695 break; 710 696 } 697 + } 698 + 699 + return 0; 700 + } 701 + 702 + /** 703 + * amdgpu_acpi_power_shift_control 704 + * 705 + * @adev: amdgpu_device pointer 706 + * @dev_state: device acpi state 707 + * @drv_state: driver state 708 + * 709 + * Executes the POWER_SHIFT_CONTROL method to 710 + * communicate current dGPU device state and 711 + * driver state to APU/SBIOS. 712 + * returns 0 on success, error on failure. 713 + */ 714 + int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, 715 + u8 dev_state, bool drv_state) 716 + { 717 + union acpi_object *info; 718 + struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs; 719 + struct atcs_pwr_shift_input atcs_input; 720 + struct acpi_buffer params; 721 + 722 + if (!amdgpu_acpi_is_power_shift_control_supported()) 723 + return -EINVAL; 724 + 725 + atcs_input.size = sizeof(struct atcs_pwr_shift_input); 726 + /* dGPU id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ 727 + atcs_input.dgpu_id = adev->pdev->devfn | (adev->pdev->bus->number << 8); 728 + atcs_input.dev_acpi_state = dev_state; 729 + atcs_input.drv_state = drv_state; 730 + 731 + params.length = sizeof(struct atcs_pwr_shift_input); 732 + params.pointer = &atcs_input; 733 + 734 + info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_POWER_SHIFT_CONTROL, &params); 735 + if (!info) { 736 + DRM_ERROR("ATCS PSC update failed\n"); 737 + return -EIO; 711 738 } 712 739 713 740 return 0;
+18
drivers/gpu/drm/amd/include/amd_acpi.h
··· 103 103 u8 ret_val; /* return value */ 104 104 } __packed; 105 105 106 + struct atcs_pwr_shift_input { 107 + u16 size; /* structure size in bytes (includes size field) */ 108 + u16 dgpu_id; /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ 109 + u8 dev_acpi_state; /* D0 = 0, D3 hot = 3 */ 110 + u8 drv_state; /* 0 = operational, 1 = not operational */ 111 + } __packed; 112 + 106 113 /* AMD hw uses four ACPI control methods: 107 114 * 1. ATIF 108 115 * ARG0: (ACPI_INTEGER) function code ··· 425 418 # define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED (1 << 1) 426 419 # define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED (1 << 2) 427 420 # define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED (1 << 3) 421 + # define ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED (1 << 7) 428 422 #define ATCS_FUNCTION_GET_EXTERNAL_STATE 0x1 429 423 /* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE 430 424 * ARG1: none ··· 478 470 * OUTPUT: 479 471 * WORD - structure size in bytes (includes size field) 480 472 * BYTE - number of active lanes 473 + */ 474 + 475 + #define ATCS_FUNCTION_POWER_SHIFT_CONTROL 0x8 476 + /* ARG0: ATCS_FUNCTION_POWER_SHIFT_CONTROL 477 + * ARG1: 478 + * WORD - structure size in bytes (includes size field) 479 + * WORD - dGPU id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) 480 + * BYTE - Device ACPI state 481 + * BYTE - Driver state 482 + * OUTPUT: none 481 483 */ 482 484 483 485 #endif