smumgr.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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 <linux/types.h>
  24. #include <linux/kernel.h>
  25. #include <linux/module.h>
  26. #include <linux/slab.h>
  27. #include <drm/amdgpu_drm.h>
  28. #include "pp_instance.h"
  29. #include "smumgr.h"
  30. #include "cgs_common.h"
  31. #include "linux/delay.h"
  32. MODULE_FIRMWARE("amdgpu/topaz_smc.bin");
  33. MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin");
  34. MODULE_FIRMWARE("amdgpu/tonga_smc.bin");
  35. MODULE_FIRMWARE("amdgpu/tonga_k_smc.bin");
  36. MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
  37. MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
  38. MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
  39. MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin");
  40. MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
  41. MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
  42. MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
  43. MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
  44. int smum_early_init(struct pp_instance *handle)
  45. {
  46. struct pp_smumgr *smumgr;
  47. if (handle == NULL)
  48. return -EINVAL;
  49. smumgr = kzalloc(sizeof(struct pp_smumgr), GFP_KERNEL);
  50. if (smumgr == NULL)
  51. return -ENOMEM;
  52. smumgr->device = handle->device;
  53. smumgr->chip_family = handle->chip_family;
  54. smumgr->chip_id = handle->chip_id;
  55. smumgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
  56. smumgr->reload_fw = 1;
  57. handle->smu_mgr = smumgr;
  58. switch (smumgr->chip_family) {
  59. case AMDGPU_FAMILY_CZ:
  60. smumgr->smumgr_funcs = &cz_smu_funcs;
  61. break;
  62. case AMDGPU_FAMILY_VI:
  63. switch (smumgr->chip_id) {
  64. case CHIP_TOPAZ:
  65. smumgr->smumgr_funcs = &iceland_smu_funcs;
  66. break;
  67. case CHIP_TONGA:
  68. smumgr->smumgr_funcs = &tonga_smu_funcs;
  69. break;
  70. case CHIP_FIJI:
  71. smumgr->smumgr_funcs = &fiji_smu_funcs;
  72. break;
  73. case CHIP_POLARIS11:
  74. case CHIP_POLARIS10:
  75. case CHIP_POLARIS12:
  76. smumgr->smumgr_funcs = &polaris10_smu_funcs;
  77. break;
  78. default:
  79. return -EINVAL;
  80. }
  81. break;
  82. case AMDGPU_FAMILY_AI:
  83. switch (smumgr->chip_id) {
  84. case CHIP_VEGA10:
  85. smumgr->smumgr_funcs = &vega10_smu_funcs;
  86. break;
  87. default:
  88. return -EINVAL;
  89. }
  90. break;
  91. default:
  92. kfree(smumgr);
  93. return -EINVAL;
  94. }
  95. return 0;
  96. }
  97. int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr,
  98. void *input, void *output, void *storage, int result)
  99. {
  100. if (NULL != hwmgr->smumgr->smumgr_funcs->thermal_avfs_enable)
  101. return hwmgr->smumgr->smumgr_funcs->thermal_avfs_enable(hwmgr);
  102. return 0;
  103. }
  104. int smum_thermal_setup_fan_table(struct pp_hwmgr *hwmgr,
  105. void *input, void *output, void *storage, int result)
  106. {
  107. if (NULL != hwmgr->smumgr->smumgr_funcs->thermal_setup_fan_table)
  108. return hwmgr->smumgr->smumgr_funcs->thermal_setup_fan_table(hwmgr);
  109. return 0;
  110. }
  111. int smum_update_sclk_threshold(struct pp_hwmgr *hwmgr)
  112. {
  113. if (NULL != hwmgr->smumgr->smumgr_funcs->update_sclk_threshold)
  114. return hwmgr->smumgr->smumgr_funcs->update_sclk_threshold(hwmgr);
  115. return 0;
  116. }
  117. int smum_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type)
  118. {
  119. if (NULL != hwmgr->smumgr->smumgr_funcs->update_smc_table)
  120. return hwmgr->smumgr->smumgr_funcs->update_smc_table(hwmgr, type);
  121. return 0;
  122. }
  123. uint32_t smum_get_offsetof(struct pp_smumgr *smumgr, uint32_t type, uint32_t member)
  124. {
  125. if (NULL != smumgr->smumgr_funcs->get_offsetof)
  126. return smumgr->smumgr_funcs->get_offsetof(type, member);
  127. return 0;
  128. }
  129. int smum_process_firmware_header(struct pp_hwmgr *hwmgr)
  130. {
  131. if (NULL != hwmgr->smumgr->smumgr_funcs->process_firmware_header)
  132. return hwmgr->smumgr->smumgr_funcs->process_firmware_header(hwmgr);
  133. return 0;
  134. }
  135. int smum_get_argument(struct pp_smumgr *smumgr)
  136. {
  137. if (NULL != smumgr->smumgr_funcs->get_argument)
  138. return smumgr->smumgr_funcs->get_argument(smumgr);
  139. return 0;
  140. }
  141. uint32_t smum_get_mac_definition(struct pp_smumgr *smumgr, uint32_t value)
  142. {
  143. if (NULL != smumgr->smumgr_funcs->get_mac_definition)
  144. return smumgr->smumgr_funcs->get_mac_definition(value);
  145. return 0;
  146. }
  147. int smum_download_powerplay_table(struct pp_smumgr *smumgr,
  148. void **table)
  149. {
  150. if (NULL != smumgr->smumgr_funcs->download_pptable_settings)
  151. return smumgr->smumgr_funcs->download_pptable_settings(smumgr,
  152. table);
  153. return 0;
  154. }
  155. int smum_upload_powerplay_table(struct pp_smumgr *smumgr)
  156. {
  157. if (NULL != smumgr->smumgr_funcs->upload_pptable_settings)
  158. return smumgr->smumgr_funcs->upload_pptable_settings(smumgr);
  159. return 0;
  160. }
  161. int smum_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
  162. {
  163. if (smumgr == NULL || smumgr->smumgr_funcs->send_msg_to_smc == NULL)
  164. return -EINVAL;
  165. return smumgr->smumgr_funcs->send_msg_to_smc(smumgr, msg);
  166. }
  167. int smum_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
  168. uint16_t msg, uint32_t parameter)
  169. {
  170. if (smumgr == NULL ||
  171. smumgr->smumgr_funcs->send_msg_to_smc_with_parameter == NULL)
  172. return -EINVAL;
  173. return smumgr->smumgr_funcs->send_msg_to_smc_with_parameter(
  174. smumgr, msg, parameter);
  175. }
  176. /*
  177. * Returns once the part of the register indicated by the mask has
  178. * reached the given value.
  179. */
  180. int smum_wait_on_register(struct pp_smumgr *smumgr,
  181. uint32_t index,
  182. uint32_t value, uint32_t mask)
  183. {
  184. uint32_t i;
  185. uint32_t cur_value;
  186. if (smumgr == NULL || smumgr->device == NULL)
  187. return -EINVAL;
  188. for (i = 0; i < smumgr->usec_timeout; i++) {
  189. cur_value = cgs_read_register(smumgr->device, index);
  190. if ((cur_value & mask) == (value & mask))
  191. break;
  192. udelay(1);
  193. }
  194. /* timeout means wrong logic*/
  195. if (i == smumgr->usec_timeout)
  196. return -1;
  197. return 0;
  198. }
  199. int smum_wait_for_register_unequal(struct pp_smumgr *smumgr,
  200. uint32_t index,
  201. uint32_t value, uint32_t mask)
  202. {
  203. uint32_t i;
  204. uint32_t cur_value;
  205. if (smumgr == NULL)
  206. return -EINVAL;
  207. for (i = 0; i < smumgr->usec_timeout; i++) {
  208. cur_value = cgs_read_register(smumgr->device,
  209. index);
  210. if ((cur_value & mask) != (value & mask))
  211. break;
  212. udelay(1);
  213. }
  214. /* timeout means wrong logic */
  215. if (i == smumgr->usec_timeout)
  216. return -1;
  217. return 0;
  218. }
  219. /*
  220. * Returns once the part of the register indicated by the mask
  221. * has reached the given value.The indirect space is described by
  222. * giving the memory-mapped index of the indirect index register.
  223. */
  224. int smum_wait_on_indirect_register(struct pp_smumgr *smumgr,
  225. uint32_t indirect_port,
  226. uint32_t index,
  227. uint32_t value,
  228. uint32_t mask)
  229. {
  230. if (smumgr == NULL || smumgr->device == NULL)
  231. return -EINVAL;
  232. cgs_write_register(smumgr->device, indirect_port, index);
  233. return smum_wait_on_register(smumgr, indirect_port + 1,
  234. mask, value);
  235. }
  236. void smum_wait_for_indirect_register_unequal(
  237. struct pp_smumgr *smumgr,
  238. uint32_t indirect_port,
  239. uint32_t index,
  240. uint32_t value,
  241. uint32_t mask)
  242. {
  243. if (smumgr == NULL || smumgr->device == NULL)
  244. return;
  245. cgs_write_register(smumgr->device, indirect_port, index);
  246. smum_wait_for_register_unequal(smumgr, indirect_port + 1,
  247. value, mask);
  248. }
  249. int smu_allocate_memory(void *device, uint32_t size,
  250. enum cgs_gpu_mem_type type,
  251. uint32_t byte_align, uint64_t *mc_addr,
  252. void **kptr, void *handle)
  253. {
  254. int ret = 0;
  255. cgs_handle_t cgs_handle;
  256. if (device == NULL || handle == NULL ||
  257. mc_addr == NULL || kptr == NULL)
  258. return -EINVAL;
  259. ret = cgs_alloc_gpu_mem(device, type, size, byte_align,
  260. 0, 0, (cgs_handle_t *)handle);
  261. if (ret)
  262. return -ENOMEM;
  263. cgs_handle = *(cgs_handle_t *)handle;
  264. ret = cgs_gmap_gpu_mem(device, cgs_handle, mc_addr);
  265. if (ret)
  266. goto error_gmap;
  267. ret = cgs_kmap_gpu_mem(device, cgs_handle, kptr);
  268. if (ret)
  269. goto error_kmap;
  270. return 0;
  271. error_kmap:
  272. cgs_gunmap_gpu_mem(device, cgs_handle);
  273. error_gmap:
  274. cgs_free_gpu_mem(device, cgs_handle);
  275. return ret;
  276. }
  277. int smu_free_memory(void *device, void *handle)
  278. {
  279. cgs_handle_t cgs_handle = (cgs_handle_t)handle;
  280. if (device == NULL || handle == NULL)
  281. return -EINVAL;
  282. cgs_kunmap_gpu_mem(device, cgs_handle);
  283. cgs_gunmap_gpu_mem(device, cgs_handle);
  284. cgs_free_gpu_mem(device, cgs_handle);
  285. return 0;
  286. }
  287. int smum_init_smc_table(struct pp_hwmgr *hwmgr)
  288. {
  289. if (NULL != hwmgr->smumgr->smumgr_funcs->init_smc_table)
  290. return hwmgr->smumgr->smumgr_funcs->init_smc_table(hwmgr);
  291. return 0;
  292. }
  293. int smum_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
  294. {
  295. if (NULL != hwmgr->smumgr->smumgr_funcs->populate_all_graphic_levels)
  296. return hwmgr->smumgr->smumgr_funcs->populate_all_graphic_levels(hwmgr);
  297. return 0;
  298. }
  299. int smum_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
  300. {
  301. if (NULL != hwmgr->smumgr->smumgr_funcs->populate_all_memory_levels)
  302. return hwmgr->smumgr->smumgr_funcs->populate_all_memory_levels(hwmgr);
  303. return 0;
  304. }
  305. /*this interface is needed by island ci/vi */
  306. int smum_initialize_mc_reg_table(struct pp_hwmgr *hwmgr)
  307. {
  308. if (NULL != hwmgr->smumgr->smumgr_funcs->initialize_mc_reg_table)
  309. return hwmgr->smumgr->smumgr_funcs->initialize_mc_reg_table(hwmgr);
  310. return 0;
  311. }
  312. bool smum_is_dpm_running(struct pp_hwmgr *hwmgr)
  313. {
  314. if (NULL != hwmgr->smumgr->smumgr_funcs->is_dpm_running)
  315. return hwmgr->smumgr->smumgr_funcs->is_dpm_running(hwmgr);
  316. return true;
  317. }
  318. int smum_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr,
  319. struct amd_pp_profile *request)
  320. {
  321. if (hwmgr->smumgr->smumgr_funcs->populate_requested_graphic_levels)
  322. return hwmgr->smumgr->smumgr_funcs->populate_requested_graphic_levels(
  323. hwmgr, request);
  324. return 0;
  325. }