tonga_smumgr.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright 2015 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 "pp_debug.h"
  24. #include <linux/types.h>
  25. #include <linux/kernel.h>
  26. #include <linux/slab.h>
  27. #include <linux/gfp.h>
  28. #include "smumgr.h"
  29. #include "tonga_smumgr.h"
  30. #include "smu_ucode_xfer_vi.h"
  31. #include "tonga_ppsmc.h"
  32. #include "smu/smu_7_1_2_d.h"
  33. #include "smu/smu_7_1_2_sh_mask.h"
  34. #include "cgs_common.h"
  35. #include "tonga_smc.h"
  36. #include "smu7_smumgr.h"
  37. static int tonga_start_in_protection_mode(struct pp_smumgr *smumgr)
  38. {
  39. int result;
  40. /* Assert reset */
  41. SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
  42. SMC_SYSCON_RESET_CNTL, rst_reg, 1);
  43. result = smu7_upload_smu_firmware_image(smumgr);
  44. if (result)
  45. return result;
  46. /* Clear status */
  47. cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
  48. ixSMU_STATUS, 0);
  49. /* Enable clock */
  50. SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
  51. SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
  52. /* De-assert reset */
  53. SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
  54. SMC_SYSCON_RESET_CNTL, rst_reg, 0);
  55. /* Set SMU Auto Start */
  56. SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
  57. SMU_INPUT_DATA, AUTO_START, 1);
  58. /* Clear firmware interrupt enable flag */
  59. cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
  60. ixFIRMWARE_FLAGS, 0);
  61. SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
  62. RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1);
  63. /**
  64. * Call Test SMU message with 0x20000 offset to trigger SMU start
  65. */
  66. smu7_send_msg_to_smc_offset(smumgr);
  67. /* Wait for done bit to be set */
  68. SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
  69. SMU_STATUS, SMU_DONE, 0);
  70. /* Check pass/failed indicator */
  71. if (1 != SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device,
  72. CGS_IND_REG__SMC, SMU_STATUS, SMU_PASS)) {
  73. pr_err("SMU Firmware start failed\n");
  74. return -EINVAL;
  75. }
  76. /* Wait for firmware to initialize */
  77. SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
  78. FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
  79. return 0;
  80. }
  81. static int tonga_start_in_non_protection_mode(struct pp_smumgr *smumgr)
  82. {
  83. int result = 0;
  84. /* wait for smc boot up */
  85. SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
  86. RCU_UC_EVENTS, boot_seq_done, 0);
  87. /*Clear firmware interrupt enable flag*/
  88. cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
  89. ixFIRMWARE_FLAGS, 0);
  90. SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
  91. SMC_SYSCON_RESET_CNTL, rst_reg, 1);
  92. result = smu7_upload_smu_firmware_image(smumgr);
  93. if (result != 0)
  94. return result;
  95. /* Set smc instruct start point at 0x0 */
  96. smu7_program_jump_on_start(smumgr);
  97. SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
  98. SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
  99. /*De-assert reset*/
  100. SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
  101. SMC_SYSCON_RESET_CNTL, rst_reg, 0);
  102. /* Wait for firmware to initialize */
  103. SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
  104. FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
  105. return result;
  106. }
  107. static int tonga_start_smu(struct pp_smumgr *smumgr)
  108. {
  109. int result;
  110. /* Only start SMC if SMC RAM is not running */
  111. if (!(smu7_is_smc_ram_running(smumgr) ||
  112. cgs_is_virtualization_enabled(smumgr->device))) {
  113. /*Check if SMU is running in protected mode*/
  114. if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
  115. SMU_FIRMWARE, SMU_MODE)) {
  116. result = tonga_start_in_non_protection_mode(smumgr);
  117. if (result)
  118. return result;
  119. } else {
  120. result = tonga_start_in_protection_mode(smumgr);
  121. if (result)
  122. return result;
  123. }
  124. }
  125. result = smu7_request_smu_load_fw(smumgr);
  126. return result;
  127. }
  128. /**
  129. * Write a 32bit value to the SMC SRAM space.
  130. * ALL PARAMETERS ARE IN HOST BYTE ORDER.
  131. * @param smumgr the address of the powerplay hardware manager.
  132. * @param smcAddress the address in the SMC RAM to access.
  133. * @param value to write to the SMC SRAM.
  134. */
  135. static int tonga_smu_init(struct pp_smumgr *smumgr)
  136. {
  137. struct tonga_smumgr *tonga_priv = NULL;
  138. int i;
  139. tonga_priv = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL);
  140. if (tonga_priv == NULL)
  141. return -ENOMEM;
  142. smumgr->backend = tonga_priv;
  143. if (smu7_init(smumgr))
  144. return -EINVAL;
  145. for (i = 0; i < SMU72_MAX_LEVELS_GRAPHICS; i++)
  146. tonga_priv->activity_target[i] = 30;
  147. return 0;
  148. }
  149. const struct pp_smumgr_func tonga_smu_funcs = {
  150. .smu_init = &tonga_smu_init,
  151. .smu_fini = &smu7_smu_fini,
  152. .start_smu = &tonga_start_smu,
  153. .check_fw_load_finish = &smu7_check_fw_load_finish,
  154. .request_smu_load_fw = &smu7_request_smu_load_fw,
  155. .request_smu_load_specific_fw = NULL,
  156. .send_msg_to_smc = &smu7_send_msg_to_smc,
  157. .send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter,
  158. .download_pptable_settings = NULL,
  159. .upload_pptable_settings = NULL,
  160. .update_smc_table = tonga_update_smc_table,
  161. .get_offsetof = tonga_get_offsetof,
  162. .process_firmware_header = tonga_process_firmware_header,
  163. .init_smc_table = tonga_init_smc_table,
  164. .update_sclk_threshold = tonga_update_sclk_threshold,
  165. .thermal_setup_fan_table = tonga_thermal_setup_fan_table,
  166. .populate_all_graphic_levels = tonga_populate_all_graphic_levels,
  167. .populate_all_memory_levels = tonga_populate_all_memory_levels,
  168. .get_mac_definition = tonga_get_mac_definition,
  169. .initialize_mc_reg_table = tonga_initialize_mc_reg_table,
  170. .is_dpm_running = tonga_is_dpm_running,
  171. .populate_requested_graphic_levels = tonga_populate_requested_graphic_levels,
  172. };