ppatomfwctrl.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  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 "ppatomfwctrl.h"
  24. #include "atomfirmware.h"
  25. #include "atom.h"
  26. #include "pp_debug.h"
  27. static const union atom_voltage_object_v4 *pp_atomfwctrl_lookup_voltage_type_v4(
  28. const struct atom_voltage_objects_info_v4_1 *voltage_object_info_table,
  29. uint8_t voltage_type, uint8_t voltage_mode)
  30. {
  31. unsigned int size = le16_to_cpu(
  32. voltage_object_info_table->table_header.structuresize);
  33. unsigned int offset =
  34. offsetof(struct atom_voltage_objects_info_v4_1, voltage_object[0]);
  35. unsigned long start = (unsigned long)voltage_object_info_table;
  36. while (offset < size) {
  37. const union atom_voltage_object_v4 *voltage_object =
  38. (const union atom_voltage_object_v4 *)(start + offset);
  39. if (voltage_type == voltage_object->gpio_voltage_obj.header.voltage_type &&
  40. voltage_mode == voltage_object->gpio_voltage_obj.header.voltage_mode)
  41. return voltage_object;
  42. offset += le16_to_cpu(voltage_object->gpio_voltage_obj.header.object_size);
  43. }
  44. return NULL;
  45. }
  46. static struct atom_voltage_objects_info_v4_1 *pp_atomfwctrl_get_voltage_info_table(
  47. struct pp_hwmgr *hwmgr)
  48. {
  49. const void *table_address;
  50. uint16_t idx;
  51. idx = GetIndexIntoMasterDataTable(voltageobject_info);
  52. table_address = smu_atom_get_data_table(hwmgr->adev,
  53. idx, NULL, NULL, NULL);
  54. PP_ASSERT_WITH_CODE(table_address,
  55. "Error retrieving BIOS Table Address!",
  56. return NULL);
  57. return (struct atom_voltage_objects_info_v4_1 *)table_address;
  58. }
  59. /**
  60. * Returns TRUE if the given voltage type is controlled by GPIO pins.
  61. * voltage_type is one of SET_VOLTAGE_TYPE_ASIC_VDDC, SET_VOLTAGE_TYPE_ASIC_MVDDC, SET_VOLTAGE_TYPE_ASIC_MVDDQ.
  62. * voltage_mode is one of ATOM_SET_VOLTAGE, ATOM_SET_VOLTAGE_PHASE
  63. */
  64. bool pp_atomfwctrl_is_voltage_controlled_by_gpio_v4(struct pp_hwmgr *hwmgr,
  65. uint8_t voltage_type, uint8_t voltage_mode)
  66. {
  67. struct atom_voltage_objects_info_v4_1 *voltage_info =
  68. (struct atom_voltage_objects_info_v4_1 *)
  69. pp_atomfwctrl_get_voltage_info_table(hwmgr);
  70. bool ret;
  71. /* If we cannot find the table do NOT try to control this voltage. */
  72. PP_ASSERT_WITH_CODE(voltage_info,
  73. "Could not find Voltage Table in BIOS.",
  74. return false);
  75. ret = (pp_atomfwctrl_lookup_voltage_type_v4(voltage_info,
  76. voltage_type, voltage_mode)) ? true : false;
  77. return ret;
  78. }
  79. int pp_atomfwctrl_get_voltage_table_v4(struct pp_hwmgr *hwmgr,
  80. uint8_t voltage_type, uint8_t voltage_mode,
  81. struct pp_atomfwctrl_voltage_table *voltage_table)
  82. {
  83. struct atom_voltage_objects_info_v4_1 *voltage_info =
  84. (struct atom_voltage_objects_info_v4_1 *)
  85. pp_atomfwctrl_get_voltage_info_table(hwmgr);
  86. const union atom_voltage_object_v4 *voltage_object;
  87. unsigned int i;
  88. int result = 0;
  89. PP_ASSERT_WITH_CODE(voltage_info,
  90. "Could not find Voltage Table in BIOS.",
  91. return -1);
  92. voltage_object = pp_atomfwctrl_lookup_voltage_type_v4(voltage_info,
  93. voltage_type, voltage_mode);
  94. if (!voltage_object)
  95. return -1;
  96. voltage_table->count = 0;
  97. if (voltage_mode == VOLTAGE_OBJ_GPIO_LUT) {
  98. PP_ASSERT_WITH_CODE(
  99. (voltage_object->gpio_voltage_obj.gpio_entry_num <=
  100. PP_ATOMFWCTRL_MAX_VOLTAGE_ENTRIES),
  101. "Too many voltage entries!",
  102. result = -1);
  103. if (!result) {
  104. for (i = 0; i < voltage_object->gpio_voltage_obj.
  105. gpio_entry_num; i++) {
  106. voltage_table->entries[i].value =
  107. le16_to_cpu(voltage_object->gpio_voltage_obj.
  108. voltage_gpio_lut[i].voltage_level_mv);
  109. voltage_table->entries[i].smio_low =
  110. le32_to_cpu(voltage_object->gpio_voltage_obj.
  111. voltage_gpio_lut[i].voltage_gpio_reg_val);
  112. }
  113. voltage_table->count =
  114. voltage_object->gpio_voltage_obj.gpio_entry_num;
  115. voltage_table->mask_low =
  116. le32_to_cpu(
  117. voltage_object->gpio_voltage_obj.gpio_mask_val);
  118. voltage_table->phase_delay =
  119. voltage_object->gpio_voltage_obj.phase_delay_us;
  120. }
  121. } else if (voltage_mode == VOLTAGE_OBJ_SVID2) {
  122. voltage_table->psi1_enable =
  123. (voltage_object->svid2_voltage_obj.loadline_psi1 & 0x20) >> 5;
  124. voltage_table->psi0_enable =
  125. voltage_object->svid2_voltage_obj.psi0_enable & 0x1;
  126. voltage_table->max_vid_step =
  127. voltage_object->svid2_voltage_obj.maxvstep;
  128. voltage_table->telemetry_offset =
  129. voltage_object->svid2_voltage_obj.telemetry_offset;
  130. voltage_table->telemetry_slope =
  131. voltage_object->svid2_voltage_obj.telemetry_gain;
  132. } else
  133. PP_ASSERT_WITH_CODE(false,
  134. "Unsupported Voltage Object Mode!",
  135. result = -1);
  136. return result;
  137. }
  138. static struct atom_gpio_pin_lut_v2_1 *pp_atomfwctrl_get_gpio_lookup_table(
  139. struct pp_hwmgr *hwmgr)
  140. {
  141. const void *table_address;
  142. uint16_t idx;
  143. idx = GetIndexIntoMasterDataTable(gpio_pin_lut);
  144. table_address = smu_atom_get_data_table(hwmgr->adev,
  145. idx, NULL, NULL, NULL);
  146. PP_ASSERT_WITH_CODE(table_address,
  147. "Error retrieving BIOS Table Address!",
  148. return NULL);
  149. return (struct atom_gpio_pin_lut_v2_1 *)table_address;
  150. }
  151. static bool pp_atomfwctrl_lookup_gpio_pin(
  152. struct atom_gpio_pin_lut_v2_1 *gpio_lookup_table,
  153. const uint32_t pin_id,
  154. struct pp_atomfwctrl_gpio_pin_assignment *gpio_pin_assignment)
  155. {
  156. unsigned int size = le16_to_cpu(
  157. gpio_lookup_table->table_header.structuresize);
  158. unsigned int offset =
  159. offsetof(struct atom_gpio_pin_lut_v2_1, gpio_pin[0]);
  160. unsigned long start = (unsigned long)gpio_lookup_table;
  161. while (offset < size) {
  162. const struct atom_gpio_pin_assignment *pin_assignment =
  163. (const struct atom_gpio_pin_assignment *)(start + offset);
  164. if (pin_id == pin_assignment->gpio_id) {
  165. gpio_pin_assignment->uc_gpio_pin_bit_shift =
  166. pin_assignment->gpio_bitshift;
  167. gpio_pin_assignment->us_gpio_pin_aindex =
  168. le16_to_cpu(pin_assignment->data_a_reg_index);
  169. return true;
  170. }
  171. offset += offsetof(struct atom_gpio_pin_assignment, gpio_id) + 1;
  172. }
  173. return false;
  174. }
  175. /**
  176. * Returns TRUE if the given pin id find in lookup table.
  177. */
  178. bool pp_atomfwctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr,
  179. const uint32_t pin_id,
  180. struct pp_atomfwctrl_gpio_pin_assignment *gpio_pin_assignment)
  181. {
  182. bool ret = false;
  183. struct atom_gpio_pin_lut_v2_1 *gpio_lookup_table =
  184. pp_atomfwctrl_get_gpio_lookup_table(hwmgr);
  185. /* If we cannot find the table do NOT try to control this voltage. */
  186. PP_ASSERT_WITH_CODE(gpio_lookup_table,
  187. "Could not find GPIO lookup Table in BIOS.",
  188. return false);
  189. ret = pp_atomfwctrl_lookup_gpio_pin(gpio_lookup_table,
  190. pin_id, gpio_pin_assignment);
  191. return ret;
  192. }
  193. /**
  194. * Enter to SelfRefresh mode.
  195. * @param hwmgr
  196. */
  197. int pp_atomfwctrl_enter_self_refresh(struct pp_hwmgr *hwmgr)
  198. {
  199. /* 0 - no action
  200. * 1 - leave power to video memory always on
  201. */
  202. return 0;
  203. }
  204. /** pp_atomfwctrl_get_gpu_pll_dividers_vega10().
  205. *
  206. * @param hwmgr input parameter: pointer to HwMgr
  207. * @param clock_type input parameter: Clock type: 1 - GFXCLK, 2 - UCLK, 0 - All other clocks
  208. * @param clock_value input parameter: Clock
  209. * @param dividers output parameter:Clock dividers
  210. */
  211. int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr,
  212. uint32_t clock_type, uint32_t clock_value,
  213. struct pp_atomfwctrl_clock_dividers_soc15 *dividers)
  214. {
  215. struct amdgpu_device *adev = hwmgr->adev;
  216. struct compute_gpu_clock_input_parameter_v1_8 pll_parameters;
  217. struct compute_gpu_clock_output_parameter_v1_8 *pll_output;
  218. uint32_t idx;
  219. pll_parameters.gpuclock_10khz = (uint32_t)clock_value;
  220. pll_parameters.gpu_clock_type = clock_type;
  221. idx = GetIndexIntoMasterCmdTable(computegpuclockparam);
  222. if (amdgpu_atom_execute_table(
  223. adev->mode_info.atom_context, idx, (uint32_t *)&pll_parameters))
  224. return -EINVAL;
  225. pll_output = (struct compute_gpu_clock_output_parameter_v1_8 *)
  226. &pll_parameters;
  227. dividers->ulClock = le32_to_cpu(pll_output->gpuclock_10khz);
  228. dividers->ulDid = le32_to_cpu(pll_output->dfs_did);
  229. dividers->ulPll_fb_mult = le32_to_cpu(pll_output->pll_fb_mult);
  230. dividers->ulPll_ss_fbsmult = le32_to_cpu(pll_output->pll_ss_fbsmult);
  231. dividers->usPll_ss_slew_frac = le16_to_cpu(pll_output->pll_ss_slew_frac);
  232. dividers->ucPll_ss_enable = pll_output->pll_ss_enable;
  233. return 0;
  234. }
  235. int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
  236. struct pp_atomfwctrl_avfs_parameters *param)
  237. {
  238. uint16_t idx;
  239. uint8_t format_revision, content_revision;
  240. struct atom_asic_profiling_info_v4_1 *profile;
  241. struct atom_asic_profiling_info_v4_2 *profile_v4_2;
  242. idx = GetIndexIntoMasterDataTable(asic_profiling_info);
  243. profile = (struct atom_asic_profiling_info_v4_1 *)
  244. smu_atom_get_data_table(hwmgr->adev,
  245. idx, NULL, NULL, NULL);
  246. if (!profile)
  247. return -1;
  248. format_revision = ((struct atom_common_table_header *)profile)->format_revision;
  249. content_revision = ((struct atom_common_table_header *)profile)->content_revision;
  250. if (format_revision == 4 && content_revision == 1) {
  251. param->ulMaxVddc = le32_to_cpu(profile->maxvddc);
  252. param->ulMinVddc = le32_to_cpu(profile->minvddc);
  253. param->ulMeanNsigmaAcontant0 =
  254. le32_to_cpu(profile->avfs_meannsigma_acontant0);
  255. param->ulMeanNsigmaAcontant1 =
  256. le32_to_cpu(profile->avfs_meannsigma_acontant1);
  257. param->ulMeanNsigmaAcontant2 =
  258. le32_to_cpu(profile->avfs_meannsigma_acontant2);
  259. param->usMeanNsigmaDcTolSigma =
  260. le16_to_cpu(profile->avfs_meannsigma_dc_tol_sigma);
  261. param->usMeanNsigmaPlatformMean =
  262. le16_to_cpu(profile->avfs_meannsigma_platform_mean);
  263. param->usMeanNsigmaPlatformSigma =
  264. le16_to_cpu(profile->avfs_meannsigma_platform_sigma);
  265. param->ulGbVdroopTableCksoffA0 =
  266. le32_to_cpu(profile->gb_vdroop_table_cksoff_a0);
  267. param->ulGbVdroopTableCksoffA1 =
  268. le32_to_cpu(profile->gb_vdroop_table_cksoff_a1);
  269. param->ulGbVdroopTableCksoffA2 =
  270. le32_to_cpu(profile->gb_vdroop_table_cksoff_a2);
  271. param->ulGbVdroopTableCksonA0 =
  272. le32_to_cpu(profile->gb_vdroop_table_ckson_a0);
  273. param->ulGbVdroopTableCksonA1 =
  274. le32_to_cpu(profile->gb_vdroop_table_ckson_a1);
  275. param->ulGbVdroopTableCksonA2 =
  276. le32_to_cpu(profile->gb_vdroop_table_ckson_a2);
  277. param->ulGbFuseTableCksoffM1 =
  278. le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1);
  279. param->ulGbFuseTableCksoffM2 =
  280. le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m2);
  281. param->ulGbFuseTableCksoffB =
  282. le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b);
  283. param->ulGbFuseTableCksonM1 =
  284. le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1);
  285. param->ulGbFuseTableCksonM2 =
  286. le32_to_cpu(profile->avfsgb_fuse_table_ckson_m2);
  287. param->ulGbFuseTableCksonB =
  288. le32_to_cpu(profile->avfsgb_fuse_table_ckson_b);
  289. param->ucEnableGbVdroopTableCkson =
  290. profile->enable_gb_vdroop_table_ckson;
  291. param->ucEnableGbFuseTableCkson =
  292. profile->enable_gb_fuse_table_ckson;
  293. param->usPsmAgeComfactor =
  294. le16_to_cpu(profile->psm_age_comfactor);
  295. param->ulDispclk2GfxclkM1 =
  296. le32_to_cpu(profile->dispclk2gfxclk_a);
  297. param->ulDispclk2GfxclkM2 =
  298. le32_to_cpu(profile->dispclk2gfxclk_b);
  299. param->ulDispclk2GfxclkB =
  300. le32_to_cpu(profile->dispclk2gfxclk_c);
  301. param->ulDcefclk2GfxclkM1 =
  302. le32_to_cpu(profile->dcefclk2gfxclk_a);
  303. param->ulDcefclk2GfxclkM2 =
  304. le32_to_cpu(profile->dcefclk2gfxclk_b);
  305. param->ulDcefclk2GfxclkB =
  306. le32_to_cpu(profile->dcefclk2gfxclk_c);
  307. param->ulPixelclk2GfxclkM1 =
  308. le32_to_cpu(profile->pixclk2gfxclk_a);
  309. param->ulPixelclk2GfxclkM2 =
  310. le32_to_cpu(profile->pixclk2gfxclk_b);
  311. param->ulPixelclk2GfxclkB =
  312. le32_to_cpu(profile->pixclk2gfxclk_c);
  313. param->ulPhyclk2GfxclkM1 =
  314. le32_to_cpu(profile->phyclk2gfxclk_a);
  315. param->ulPhyclk2GfxclkM2 =
  316. le32_to_cpu(profile->phyclk2gfxclk_b);
  317. param->ulPhyclk2GfxclkB =
  318. le32_to_cpu(profile->phyclk2gfxclk_c);
  319. param->ulAcgGbVdroopTableA0 = 0;
  320. param->ulAcgGbVdroopTableA1 = 0;
  321. param->ulAcgGbVdroopTableA2 = 0;
  322. param->ulAcgGbFuseTableM1 = 0;
  323. param->ulAcgGbFuseTableM2 = 0;
  324. param->ulAcgGbFuseTableB = 0;
  325. param->ucAcgEnableGbVdroopTable = 0;
  326. param->ucAcgEnableGbFuseTable = 0;
  327. } else if (format_revision == 4 && content_revision == 2) {
  328. profile_v4_2 = (struct atom_asic_profiling_info_v4_2 *)profile;
  329. param->ulMaxVddc = le32_to_cpu(profile_v4_2->maxvddc);
  330. param->ulMinVddc = le32_to_cpu(profile_v4_2->minvddc);
  331. param->ulMeanNsigmaAcontant0 =
  332. le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant0);
  333. param->ulMeanNsigmaAcontant1 =
  334. le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant1);
  335. param->ulMeanNsigmaAcontant2 =
  336. le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant2);
  337. param->usMeanNsigmaDcTolSigma =
  338. le16_to_cpu(profile_v4_2->avfs_meannsigma_dc_tol_sigma);
  339. param->usMeanNsigmaPlatformMean =
  340. le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_mean);
  341. param->usMeanNsigmaPlatformSigma =
  342. le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_sigma);
  343. param->ulGbVdroopTableCksoffA0 =
  344. le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a0);
  345. param->ulGbVdroopTableCksoffA1 =
  346. le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a1);
  347. param->ulGbVdroopTableCksoffA2 =
  348. le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a2);
  349. param->ulGbVdroopTableCksonA0 =
  350. le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a0);
  351. param->ulGbVdroopTableCksonA1 =
  352. le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a1);
  353. param->ulGbVdroopTableCksonA2 =
  354. le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a2);
  355. param->ulGbFuseTableCksoffM1 =
  356. le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m1);
  357. param->ulGbFuseTableCksoffM2 =
  358. le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m2);
  359. param->ulGbFuseTableCksoffB =
  360. le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_b);
  361. param->ulGbFuseTableCksonM1 =
  362. le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m1);
  363. param->ulGbFuseTableCksonM2 =
  364. le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m2);
  365. param->ulGbFuseTableCksonB =
  366. le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_b);
  367. param->ucEnableGbVdroopTableCkson =
  368. profile_v4_2->enable_gb_vdroop_table_ckson;
  369. param->ucEnableGbFuseTableCkson =
  370. profile_v4_2->enable_gb_fuse_table_ckson;
  371. param->usPsmAgeComfactor =
  372. le16_to_cpu(profile_v4_2->psm_age_comfactor);
  373. param->ulDispclk2GfxclkM1 =
  374. le32_to_cpu(profile_v4_2->dispclk2gfxclk_a);
  375. param->ulDispclk2GfxclkM2 =
  376. le32_to_cpu(profile_v4_2->dispclk2gfxclk_b);
  377. param->ulDispclk2GfxclkB =
  378. le32_to_cpu(profile_v4_2->dispclk2gfxclk_c);
  379. param->ulDcefclk2GfxclkM1 =
  380. le32_to_cpu(profile_v4_2->dcefclk2gfxclk_a);
  381. param->ulDcefclk2GfxclkM2 =
  382. le32_to_cpu(profile_v4_2->dcefclk2gfxclk_b);
  383. param->ulDcefclk2GfxclkB =
  384. le32_to_cpu(profile_v4_2->dcefclk2gfxclk_c);
  385. param->ulPixelclk2GfxclkM1 =
  386. le32_to_cpu(profile_v4_2->pixclk2gfxclk_a);
  387. param->ulPixelclk2GfxclkM2 =
  388. le32_to_cpu(profile_v4_2->pixclk2gfxclk_b);
  389. param->ulPixelclk2GfxclkB =
  390. le32_to_cpu(profile_v4_2->pixclk2gfxclk_c);
  391. param->ulPhyclk2GfxclkM1 =
  392. le32_to_cpu(profile->phyclk2gfxclk_a);
  393. param->ulPhyclk2GfxclkM2 =
  394. le32_to_cpu(profile_v4_2->phyclk2gfxclk_b);
  395. param->ulPhyclk2GfxclkB =
  396. le32_to_cpu(profile_v4_2->phyclk2gfxclk_c);
  397. param->ulAcgGbVdroopTableA0 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a0);
  398. param->ulAcgGbVdroopTableA1 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a1);
  399. param->ulAcgGbVdroopTableA2 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a2);
  400. param->ulAcgGbFuseTableM1 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m1);
  401. param->ulAcgGbFuseTableM2 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m2);
  402. param->ulAcgGbFuseTableB = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_b);
  403. param->ucAcgEnableGbVdroopTable = le32_to_cpu(profile_v4_2->enable_acg_gb_vdroop_table);
  404. param->ucAcgEnableGbFuseTable = le32_to_cpu(profile_v4_2->enable_acg_gb_fuse_table);
  405. } else {
  406. pr_info("Invalid VBIOS AVFS ProfilingInfo Revision!\n");
  407. return -EINVAL;
  408. }
  409. return 0;
  410. }
  411. int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,
  412. struct pp_atomfwctrl_gpio_parameters *param)
  413. {
  414. struct atom_smu_info_v3_1 *info;
  415. uint16_t idx;
  416. idx = GetIndexIntoMasterDataTable(smu_info);
  417. info = (struct atom_smu_info_v3_1 *)
  418. smu_atom_get_data_table(hwmgr->adev,
  419. idx, NULL, NULL, NULL);
  420. if (!info) {
  421. pr_info("Error retrieving BIOS smu_info Table Address!");
  422. return -1;
  423. }
  424. param->ucAcDcGpio = info->ac_dc_gpio_bit;
  425. param->ucAcDcPolarity = info->ac_dc_polarity;
  426. param->ucVR0HotGpio = info->vr0hot_gpio_bit;
  427. param->ucVR0HotPolarity = info->vr0hot_polarity;
  428. param->ucVR1HotGpio = info->vr1hot_gpio_bit;
  429. param->ucVR1HotPolarity = info->vr1hot_polarity;
  430. param->ucFwCtfGpio = info->fw_ctf_gpio_bit;
  431. param->ucFwCtfPolarity = info->fw_ctf_polarity;
  432. return 0;
  433. }
  434. int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, BIOS_CLKID id, uint32_t *frequency)
  435. {
  436. struct amdgpu_device *adev = hwmgr->adev;
  437. struct atom_get_smu_clock_info_parameters_v3_1 parameters;
  438. struct atom_get_smu_clock_info_output_parameters_v3_1 *output;
  439. uint32_t ix;
  440. parameters.clk_id = id;
  441. parameters.syspll_id = 0;
  442. parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ;
  443. parameters.dfsdid = 0;
  444. ix = GetIndexIntoMasterCmdTable(getsmuclockinfo);
  445. if (amdgpu_atom_execute_table(
  446. adev->mode_info.atom_context, ix, (uint32_t *)&parameters))
  447. return -EINVAL;
  448. output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)&parameters;
  449. *frequency = le32_to_cpu(output->atom_smu_outputclkfreq.smu_clock_freq_hz) / 10000;
  450. return 0;
  451. }
  452. static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr,
  453. struct pp_atomfwctrl_bios_boot_up_values *boot_values,
  454. struct atom_firmware_info_v3_2 *fw_info)
  455. {
  456. uint32_t frequency = 0;
  457. boot_values->ulRevision = fw_info->firmware_revision;
  458. boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz;
  459. boot_values->ulUClk = fw_info->bootup_mclk_in10khz;
  460. boot_values->usVddc = fw_info->bootup_vddc_mv;
  461. boot_values->usVddci = fw_info->bootup_vddci_mv;
  462. boot_values->usMvddc = fw_info->bootup_mvddc_mv;
  463. boot_values->usVddGfx = fw_info->bootup_vddgfx_mv;
  464. boot_values->ucCoolingID = fw_info->coolingsolution_id;
  465. boot_values->ulSocClk = 0;
  466. boot_values->ulDCEFClk = 0;
  467. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, &frequency))
  468. boot_values->ulSocClk = frequency;
  469. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, &frequency))
  470. boot_values->ulDCEFClk = frequency;
  471. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, &frequency))
  472. boot_values->ulEClk = frequency;
  473. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, &frequency))
  474. boot_values->ulVClk = frequency;
  475. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, &frequency))
  476. boot_values->ulDClk = frequency;
  477. }
  478. static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr,
  479. struct pp_atomfwctrl_bios_boot_up_values *boot_values,
  480. struct atom_firmware_info_v3_1 *fw_info)
  481. {
  482. uint32_t frequency = 0;
  483. boot_values->ulRevision = fw_info->firmware_revision;
  484. boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz;
  485. boot_values->ulUClk = fw_info->bootup_mclk_in10khz;
  486. boot_values->usVddc = fw_info->bootup_vddc_mv;
  487. boot_values->usVddci = fw_info->bootup_vddci_mv;
  488. boot_values->usMvddc = fw_info->bootup_mvddc_mv;
  489. boot_values->usVddGfx = fw_info->bootup_vddgfx_mv;
  490. boot_values->ucCoolingID = fw_info->coolingsolution_id;
  491. boot_values->ulSocClk = 0;
  492. boot_values->ulDCEFClk = 0;
  493. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, &frequency))
  494. boot_values->ulSocClk = frequency;
  495. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, &frequency))
  496. boot_values->ulDCEFClk = frequency;
  497. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, &frequency))
  498. boot_values->ulEClk = frequency;
  499. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, &frequency))
  500. boot_values->ulVClk = frequency;
  501. if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, &frequency))
  502. boot_values->ulDClk = frequency;
  503. }
  504. int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
  505. struct pp_atomfwctrl_bios_boot_up_values *boot_values)
  506. {
  507. struct atom_firmware_info_v3_2 *fwinfo_3_2;
  508. struct atom_firmware_info_v3_1 *fwinfo_3_1;
  509. struct atom_common_table_header *info = NULL;
  510. uint16_t ix;
  511. ix = GetIndexIntoMasterDataTable(firmwareinfo);
  512. info = (struct atom_common_table_header *)
  513. smu_atom_get_data_table(hwmgr->adev,
  514. ix, NULL, NULL, NULL);
  515. if (!info) {
  516. pr_info("Error retrieving BIOS firmwareinfo!");
  517. return -EINVAL;
  518. }
  519. if ((info->format_revision == 3) && (info->content_revision == 2)) {
  520. fwinfo_3_2 = (struct atom_firmware_info_v3_2 *)info;
  521. pp_atomfwctrl_copy_vbios_bootup_values_3_2(hwmgr,
  522. boot_values, fwinfo_3_2);
  523. } else if ((info->format_revision == 3) && (info->content_revision == 1)) {
  524. fwinfo_3_1 = (struct atom_firmware_info_v3_1 *)info;
  525. pp_atomfwctrl_copy_vbios_bootup_values_3_1(hwmgr,
  526. boot_values, fwinfo_3_1);
  527. } else {
  528. pr_info("Fw info table revision does not match!");
  529. return -EINVAL;
  530. }
  531. return 0;
  532. }
  533. int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,
  534. struct pp_atomfwctrl_smc_dpm_parameters *param)
  535. {
  536. struct atom_smc_dpm_info_v4_1 *info;
  537. uint16_t ix;
  538. ix = GetIndexIntoMasterDataTable(smc_dpm_info);
  539. info = (struct atom_smc_dpm_info_v4_1 *)
  540. smu_atom_get_data_table(hwmgr->adev,
  541. ix, NULL, NULL, NULL);
  542. if (!info) {
  543. pr_info("Error retrieving BIOS Table Address!");
  544. return -EINVAL;
  545. }
  546. param->liquid1_i2c_address = info->liquid1_i2c_address;
  547. param->liquid2_i2c_address = info->liquid2_i2c_address;
  548. param->vr_i2c_address = info->vr_i2c_address;
  549. param->plx_i2c_address = info->plx_i2c_address;
  550. param->liquid_i2c_linescl = info->liquid_i2c_linescl;
  551. param->liquid_i2c_linesda = info->liquid_i2c_linesda;
  552. param->vr_i2c_linescl = info->vr_i2c_linescl;
  553. param->vr_i2c_linesda = info->vr_i2c_linesda;
  554. param->plx_i2c_linescl = info->plx_i2c_linescl;
  555. param->plx_i2c_linesda = info->plx_i2c_linesda;
  556. param->vrsensorpresent = info->vrsensorpresent;
  557. param->liquidsensorpresent = info->liquidsensorpresent;
  558. param->maxvoltagestepgfx = info->maxvoltagestepgfx;
  559. param->maxvoltagestepsoc = info->maxvoltagestepsoc;
  560. param->vddgfxvrmapping = info->vddgfxvrmapping;
  561. param->vddsocvrmapping = info->vddsocvrmapping;
  562. param->vddmem0vrmapping = info->vddmem0vrmapping;
  563. param->vddmem1vrmapping = info->vddmem1vrmapping;
  564. param->gfxulvphasesheddingmask = info->gfxulvphasesheddingmask;
  565. param->soculvphasesheddingmask = info->soculvphasesheddingmask;
  566. param->gfxmaxcurrent = info->gfxmaxcurrent;
  567. param->gfxoffset = info->gfxoffset;
  568. param->padding_telemetrygfx = info->padding_telemetrygfx;
  569. param->socmaxcurrent = info->socmaxcurrent;
  570. param->socoffset = info->socoffset;
  571. param->padding_telemetrysoc = info->padding_telemetrysoc;
  572. param->mem0maxcurrent = info->mem0maxcurrent;
  573. param->mem0offset = info->mem0offset;
  574. param->padding_telemetrymem0 = info->padding_telemetrymem0;
  575. param->mem1maxcurrent = info->mem1maxcurrent;
  576. param->mem1offset = info->mem1offset;
  577. param->padding_telemetrymem1 = info->padding_telemetrymem1;
  578. param->acdcgpio = info->acdcgpio;
  579. param->acdcpolarity = info->acdcpolarity;
  580. param->vr0hotgpio = info->vr0hotgpio;
  581. param->vr0hotpolarity = info->vr0hotpolarity;
  582. param->vr1hotgpio = info->vr1hotgpio;
  583. param->vr1hotpolarity = info->vr1hotpolarity;
  584. param->padding1 = info->padding1;
  585. param->padding2 = info->padding2;
  586. param->ledpin0 = info->ledpin0;
  587. param->ledpin1 = info->ledpin1;
  588. param->ledpin2 = info->ledpin2;
  589. param->pllgfxclkspreadenabled = info->pllgfxclkspreadenabled;
  590. param->pllgfxclkspreadpercent = info->pllgfxclkspreadpercent;
  591. param->pllgfxclkspreadfreq = info->pllgfxclkspreadfreq;
  592. param->uclkspreadenabled = info->uclkspreadenabled;
  593. param->uclkspreadpercent = info->uclkspreadpercent;
  594. param->uclkspreadfreq = info->uclkspreadfreq;
  595. param->socclkspreadenabled = info->socclkspreadenabled;
  596. param->socclkspreadpercent = info->socclkspreadpercent;
  597. param->socclkspreadfreq = info->socclkspreadfreq;
  598. param->acggfxclkspreadenabled = info->acggfxclkspreadenabled;
  599. param->acggfxclkspreadpercent = info->acggfxclkspreadpercent;
  600. param->acggfxclkspreadfreq = info->acggfxclkspreadfreq;
  601. param->Vr2_I2C_address = info->Vr2_I2C_address;
  602. return 0;
  603. }