linux/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
<<
>>
Prefs
   1#include <linux/errno.h>
   2#include "linux/delay.h"
   3#include "hwmgr.h"
   4#include "amd_acpi.h"
   5
   6bool acpi_atcs_functions_supported(void *device, uint32_t index)
   7{
   8        int32_t result;
   9        struct atcs_verify_interface output_buf = {0};
  10
  11        int32_t temp_buffer = 1;
  12
  13        result = cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
  14                                                ATCS_FUNCTION_VERIFY_INTERFACE,
  15                                                &temp_buffer,
  16                                                &output_buf,
  17                                                1,
  18                                                sizeof(temp_buffer),
  19                                                sizeof(output_buf));
  20
  21        return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false;
  22}
  23
  24int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
  25{
  26        struct atcs_pref_req_input atcs_input;
  27        struct atcs_pref_req_output atcs_output;
  28        u32 retry = 3;
  29        int result;
  30        struct cgs_system_info info = {0};
  31
  32        if (!acpi_atcs_functions_supported(device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST))
  33                return -EINVAL;
  34
  35        info.size = sizeof(struct cgs_system_info);
  36        info.info_id = CGS_SYSTEM_INFO_ADAPTER_BDF_ID;
  37        result = cgs_query_system_info(device, &info);
  38        if (result != 0)
  39                return -EINVAL;
  40        atcs_input.client_id = (uint16_t)info.value;
  41        atcs_input.size = sizeof(struct atcs_pref_req_input);
  42        atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
  43        atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
  44        if (advertise)
  45                atcs_input.flags |= ATCS_ADVERTISE_CAPS;
  46        atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
  47        atcs_input.perf_req = perf_req;
  48
  49        atcs_output.size = sizeof(struct atcs_pref_req_input);
  50
  51        while (retry--) {
  52                result = cgs_call_acpi_method(device,
  53                                                CGS_ACPI_METHOD_ATCS,
  54                                                ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST,
  55                                                &atcs_input,
  56                                                &atcs_output,
  57                                                0,
  58                                                sizeof(atcs_input),
  59                                                sizeof(atcs_output));
  60                if (result != 0)
  61                        return -EIO;
  62
  63                switch (atcs_output.ret_val) {
  64                case ATCS_REQUEST_REFUSED:
  65                default:
  66                        return -EINVAL;
  67                case ATCS_REQUEST_COMPLETE:
  68                        return 0;
  69                case ATCS_REQUEST_IN_PROGRESS:
  70                        udelay(10);
  71                        break;
  72                }
  73        }
  74
  75        return 0;
  76}
  77