pp_acpi.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Copyright 2016 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. #include <linux/errno.h>
  24. #include "linux/delay.h"
  25. #include "hwmgr.h"
  26. #include "amd_acpi.h"
  27. #include "pp_acpi.h"
  28. bool acpi_atcs_functions_supported(void *device, uint32_t index)
  29. {
  30. int32_t result;
  31. struct atcs_verify_interface output_buf = {0};
  32. int32_t temp_buffer = 1;
  33. result = cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
  34. ATCS_FUNCTION_VERIFY_INTERFACE,
  35. &temp_buffer,
  36. &output_buf,
  37. 1,
  38. sizeof(temp_buffer),
  39. sizeof(output_buf));
  40. return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false;
  41. }
  42. bool acpi_atcs_notify_pcie_device_ready(void *device)
  43. {
  44. int32_t temp_buffer = 1;
  45. return cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
  46. ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION,
  47. &temp_buffer,
  48. NULL,
  49. 0,
  50. sizeof(temp_buffer),
  51. 0);
  52. }
  53. int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
  54. {
  55. struct atcs_pref_req_input atcs_input;
  56. struct atcs_pref_req_output atcs_output;
  57. u32 retry = 3;
  58. int result;
  59. struct cgs_system_info info = {0};
  60. if (acpi_atcs_notify_pcie_device_ready(device))
  61. return -EINVAL;
  62. info.size = sizeof(struct cgs_system_info);
  63. info.info_id = CGS_SYSTEM_INFO_ADAPTER_BDF_ID;
  64. result = cgs_query_system_info(device, &info);
  65. if (result != 0)
  66. return -EINVAL;
  67. atcs_input.client_id = (uint16_t)info.value;
  68. atcs_input.size = sizeof(struct atcs_pref_req_input);
  69. atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
  70. atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
  71. if (advertise)
  72. atcs_input.flags |= ATCS_ADVERTISE_CAPS;
  73. atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
  74. atcs_input.perf_req = perf_req;
  75. atcs_output.size = sizeof(struct atcs_pref_req_input);
  76. while (retry--) {
  77. result = cgs_call_acpi_method(device,
  78. CGS_ACPI_METHOD_ATCS,
  79. ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST,
  80. &atcs_input,
  81. &atcs_output,
  82. 1,
  83. sizeof(atcs_input),
  84. sizeof(atcs_output));
  85. if (result != 0)
  86. return -EIO;
  87. switch (atcs_output.ret_val) {
  88. case ATCS_REQUEST_REFUSED:
  89. default:
  90. return -EINVAL;
  91. case ATCS_REQUEST_COMPLETE:
  92. return 0;
  93. case ATCS_REQUEST_IN_PROGRESS:
  94. udelay(10);
  95. break;
  96. }
  97. }
  98. return 0;
  99. }