vega10_processpptables.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325
  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/module.h>
  24. #include <linux/slab.h>
  25. #include <linux/fb.h>
  26. #include "vega10_processpptables.h"
  27. #include "ppatomfwctrl.h"
  28. #include "atomfirmware.h"
  29. #include "pp_debug.h"
  30. #include "cgs_common.h"
  31. #include "vega10_pptable.h"
  32. #define NUM_DSPCLK_LEVELS 8
  33. #define VEGA10_ENGINECLOCK_HARDMAX 198000
  34. static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
  35. enum phm_platform_caps cap)
  36. {
  37. if (enable)
  38. phm_cap_set(hwmgr->platform_descriptor.platformCaps, cap);
  39. else
  40. phm_cap_unset(hwmgr->platform_descriptor.platformCaps, cap);
  41. }
  42. static const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
  43. {
  44. int index = GetIndexIntoMasterDataTable(powerplayinfo);
  45. u16 size;
  46. u8 frev, crev;
  47. const void *table_address = hwmgr->soft_pp_table;
  48. if (!table_address) {
  49. table_address = (ATOM_Vega10_POWERPLAYTABLE *)
  50. smu_atom_get_data_table(hwmgr->adev, index,
  51. &size, &frev, &crev);
  52. hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/
  53. hwmgr->soft_pp_table_size = size;
  54. }
  55. return table_address;
  56. }
  57. static int check_powerplay_tables(
  58. struct pp_hwmgr *hwmgr,
  59. const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
  60. {
  61. const ATOM_Vega10_State_Array *state_arrays;
  62. state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)powerplay_table) +
  63. le16_to_cpu(powerplay_table->usStateArrayOffset));
  64. PP_ASSERT_WITH_CODE((powerplay_table->sHeader.format_revision >=
  65. ATOM_Vega10_TABLE_REVISION_VEGA10),
  66. "Unsupported PPTable format!", return -1);
  67. PP_ASSERT_WITH_CODE(powerplay_table->usStateArrayOffset,
  68. "State table is not set!", return -1);
  69. PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0,
  70. "Invalid PowerPlay Table!", return -1);
  71. PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0,
  72. "Invalid PowerPlay Table!", return -1);
  73. return 0;
  74. }
  75. static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
  76. {
  77. set_hw_cap(
  78. hwmgr,
  79. 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_POWERPLAY),
  80. PHM_PlatformCaps_PowerPlaySupport);
  81. set_hw_cap(
  82. hwmgr,
  83. 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_SBIOSPOWERSOURCE),
  84. PHM_PlatformCaps_BiosPowerSourceControl);
  85. set_hw_cap(
  86. hwmgr,
  87. 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_HARDWAREDC),
  88. PHM_PlatformCaps_AutomaticDCTransition);
  89. set_hw_cap(
  90. hwmgr,
  91. 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_CAP_BACO),
  92. PHM_PlatformCaps_BACO);
  93. set_hw_cap(
  94. hwmgr,
  95. 0 != (powerplay_caps & ATOM_VEGA10_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL),
  96. PHM_PlatformCaps_CombinePCCWithThermalSignal);
  97. return 0;
  98. }
  99. static int init_thermal_controller(
  100. struct pp_hwmgr *hwmgr,
  101. const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
  102. {
  103. const ATOM_Vega10_Thermal_Controller *thermal_controller;
  104. const Vega10_PPTable_Generic_SubTable_Header *header;
  105. const ATOM_Vega10_Fan_Table *fan_table_v1;
  106. const ATOM_Vega10_Fan_Table_V2 *fan_table_v2;
  107. thermal_controller = (ATOM_Vega10_Thermal_Controller *)
  108. (((unsigned long)powerplay_table) +
  109. le16_to_cpu(powerplay_table->usThermalControllerOffset));
  110. PP_ASSERT_WITH_CODE((powerplay_table->usThermalControllerOffset != 0),
  111. "Thermal controller table not set!", return -EINVAL);
  112. hwmgr->thermal_controller.ucType = thermal_controller->ucType;
  113. hwmgr->thermal_controller.ucI2cLine = thermal_controller->ucI2cLine;
  114. hwmgr->thermal_controller.ucI2cAddress = thermal_controller->ucI2cAddress;
  115. hwmgr->thermal_controller.fanInfo.bNoFan =
  116. (0 != (thermal_controller->ucFanParameters &
  117. ATOM_VEGA10_PP_FANPARAMETERS_NOFAN));
  118. hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
  119. thermal_controller->ucFanParameters &
  120. ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
  121. hwmgr->thermal_controller.fanInfo.ulMinRPM =
  122. thermal_controller->ucFanMinRPM * 100UL;
  123. hwmgr->thermal_controller.fanInfo.ulMaxRPM =
  124. thermal_controller->ucFanMaxRPM * 100UL;
  125. hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay
  126. = 100000;
  127. set_hw_cap(
  128. hwmgr,
  129. ATOM_VEGA10_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
  130. PHM_PlatformCaps_ThermalController);
  131. if (!powerplay_table->usFanTableOffset)
  132. return 0;
  133. header = (const Vega10_PPTable_Generic_SubTable_Header *)
  134. (((unsigned long)powerplay_table) +
  135. le16_to_cpu(powerplay_table->usFanTableOffset));
  136. if (header->ucRevId == 10) {
  137. fan_table_v1 = (ATOM_Vega10_Fan_Table *)header;
  138. PP_ASSERT_WITH_CODE((fan_table_v1->ucRevId >= 8),
  139. "Invalid Input Fan Table!", return -EINVAL);
  140. phm_cap_set(hwmgr->platform_descriptor.platformCaps,
  141. PHM_PlatformCaps_MicrocodeFanControl);
  142. hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
  143. le16_to_cpu(fan_table_v1->usFanOutputSensitivity);
  144. hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM =
  145. le16_to_cpu(fan_table_v1->usFanRPMMax);
  146. hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit =
  147. le16_to_cpu(fan_table_v1->usThrottlingRPM);
  148. hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit =
  149. le16_to_cpu(fan_table_v1->usFanAcousticLimit);
  150. hwmgr->thermal_controller.advanceFanControlParameters.usTMax =
  151. le16_to_cpu(fan_table_v1->usTargetTemperature);
  152. hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin =
  153. le16_to_cpu(fan_table_v1->usMinimumPWMLimit);
  154. hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk =
  155. le16_to_cpu(fan_table_v1->usTargetGfxClk);
  156. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge =
  157. le16_to_cpu(fan_table_v1->usFanGainEdge);
  158. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot =
  159. le16_to_cpu(fan_table_v1->usFanGainHotspot);
  160. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid =
  161. le16_to_cpu(fan_table_v1->usFanGainLiquid);
  162. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc =
  163. le16_to_cpu(fan_table_v1->usFanGainVrVddc);
  164. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd =
  165. le16_to_cpu(fan_table_v1->usFanGainVrMvdd);
  166. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx =
  167. le16_to_cpu(fan_table_v1->usFanGainPlx);
  168. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm =
  169. le16_to_cpu(fan_table_v1->usFanGainHbm);
  170. hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM =
  171. fan_table_v1->ucEnableZeroRPM;
  172. hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature =
  173. le16_to_cpu(fan_table_v1->usFanStopTemperature);
  174. hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature =
  175. le16_to_cpu(fan_table_v1->usFanStartTemperature);
  176. } else if (header->ucRevId > 10) {
  177. fan_table_v2 = (ATOM_Vega10_Fan_Table_V2 *)header;
  178. hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
  179. fan_table_v2->ucFanParameters & ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
  180. hwmgr->thermal_controller.fanInfo.ulMinRPM = fan_table_v2->ucFanMinRPM * 100UL;
  181. hwmgr->thermal_controller.fanInfo.ulMaxRPM = fan_table_v2->ucFanMaxRPM * 100UL;
  182. phm_cap_set(hwmgr->platform_descriptor.platformCaps,
  183. PHM_PlatformCaps_MicrocodeFanControl);
  184. hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity =
  185. le16_to_cpu(fan_table_v2->usFanOutputSensitivity);
  186. hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM =
  187. fan_table_v2->ucFanMaxRPM * 100UL;
  188. hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMMaxLimit =
  189. le16_to_cpu(fan_table_v2->usThrottlingRPM);
  190. hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit =
  191. le16_to_cpu(fan_table_v2->usFanAcousticLimitRpm);
  192. hwmgr->thermal_controller.advanceFanControlParameters.usTMax =
  193. le16_to_cpu(fan_table_v2->usTargetTemperature);
  194. hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin =
  195. le16_to_cpu(fan_table_v2->usMinimumPWMLimit);
  196. hwmgr->thermal_controller.advanceFanControlParameters.ulTargetGfxClk =
  197. le16_to_cpu(fan_table_v2->usTargetGfxClk);
  198. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge =
  199. le16_to_cpu(fan_table_v2->usFanGainEdge);
  200. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot =
  201. le16_to_cpu(fan_table_v2->usFanGainHotspot);
  202. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid =
  203. le16_to_cpu(fan_table_v2->usFanGainLiquid);
  204. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc =
  205. le16_to_cpu(fan_table_v2->usFanGainVrVddc);
  206. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd =
  207. le16_to_cpu(fan_table_v2->usFanGainVrMvdd);
  208. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx =
  209. le16_to_cpu(fan_table_v2->usFanGainPlx);
  210. hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm =
  211. le16_to_cpu(fan_table_v2->usFanGainHbm);
  212. hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM =
  213. fan_table_v2->ucEnableZeroRPM;
  214. hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStopTemperature =
  215. le16_to_cpu(fan_table_v2->usFanStopTemperature);
  216. hwmgr->thermal_controller.advanceFanControlParameters.usZeroRPMStartTemperature =
  217. le16_to_cpu(fan_table_v2->usFanStartTemperature);
  218. }
  219. return 0;
  220. }
  221. static int init_over_drive_limits(
  222. struct pp_hwmgr *hwmgr,
  223. const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
  224. {
  225. const ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table =
  226. (const ATOM_Vega10_GFXCLK_Dependency_Table *)
  227. (((unsigned long) powerplay_table) +
  228. le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset));
  229. bool is_acg_enabled = false;
  230. ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2;
  231. if (gfxclk_dep_table->ucRevId == 1) {
  232. patom_record_v2 =
  233. (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)gfxclk_dep_table->entries;
  234. is_acg_enabled =
  235. (bool)patom_record_v2[gfxclk_dep_table->ucNumEntries-1].ucACGEnable;
  236. }
  237. if (powerplay_table->ulMaxODEngineClock > VEGA10_ENGINECLOCK_HARDMAX &&
  238. !is_acg_enabled)
  239. hwmgr->platform_descriptor.overdriveLimit.engineClock =
  240. VEGA10_ENGINECLOCK_HARDMAX;
  241. else
  242. hwmgr->platform_descriptor.overdriveLimit.engineClock =
  243. le32_to_cpu(powerplay_table->ulMaxODEngineClock);
  244. hwmgr->platform_descriptor.overdriveLimit.memoryClock =
  245. le32_to_cpu(powerplay_table->ulMaxODMemoryClock);
  246. hwmgr->platform_descriptor.minOverdriveVDDC = 0;
  247. hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
  248. hwmgr->platform_descriptor.overdriveVDDCStep = 0;
  249. return 0;
  250. }
  251. static int get_mm_clock_voltage_table(
  252. struct pp_hwmgr *hwmgr,
  253. phm_ppt_v1_mm_clock_voltage_dependency_table **vega10_mm_table,
  254. const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table)
  255. {
  256. uint32_t table_size, i;
  257. const ATOM_Vega10_MM_Dependency_Record *mm_dependency_record;
  258. phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table;
  259. PP_ASSERT_WITH_CODE((mm_dependency_table->ucNumEntries != 0),
  260. "Invalid PowerPlay Table!", return -1);
  261. table_size = sizeof(uint32_t) +
  262. sizeof(phm_ppt_v1_mm_clock_voltage_dependency_record) *
  263. mm_dependency_table->ucNumEntries;
  264. mm_table = kzalloc(table_size, GFP_KERNEL);
  265. if (!mm_table)
  266. return -ENOMEM;
  267. mm_table->count = mm_dependency_table->ucNumEntries;
  268. for (i = 0; i < mm_dependency_table->ucNumEntries; i++) {
  269. mm_dependency_record = &mm_dependency_table->entries[i];
  270. mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd;
  271. mm_table->entries[i].samclock =
  272. le32_to_cpu(mm_dependency_record->ulPSPClk);
  273. mm_table->entries[i].eclk = le32_to_cpu(mm_dependency_record->ulEClk);
  274. mm_table->entries[i].vclk = le32_to_cpu(mm_dependency_record->ulVClk);
  275. mm_table->entries[i].dclk = le32_to_cpu(mm_dependency_record->ulDClk);
  276. }
  277. *vega10_mm_table = mm_table;
  278. return 0;
  279. }
  280. static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t* sda)
  281. {
  282. switch(line){
  283. case Vega10_I2CLineID_DDC1:
  284. *scl = Vega10_I2C_DDC1CLK;
  285. *sda = Vega10_I2C_DDC1DATA;
  286. break;
  287. case Vega10_I2CLineID_DDC2:
  288. *scl = Vega10_I2C_DDC2CLK;
  289. *sda = Vega10_I2C_DDC2DATA;
  290. break;
  291. case Vega10_I2CLineID_DDC3:
  292. *scl = Vega10_I2C_DDC3CLK;
  293. *sda = Vega10_I2C_DDC3DATA;
  294. break;
  295. case Vega10_I2CLineID_DDC4:
  296. *scl = Vega10_I2C_DDC4CLK;
  297. *sda = Vega10_I2C_DDC4DATA;
  298. break;
  299. case Vega10_I2CLineID_DDC5:
  300. *scl = Vega10_I2C_DDC5CLK;
  301. *sda = Vega10_I2C_DDC5DATA;
  302. break;
  303. case Vega10_I2CLineID_DDC6:
  304. *scl = Vega10_I2C_DDC6CLK;
  305. *sda = Vega10_I2C_DDC6DATA;
  306. break;
  307. case Vega10_I2CLineID_SCLSDA:
  308. *scl = Vega10_I2C_SCL;
  309. *sda = Vega10_I2C_SDA;
  310. break;
  311. case Vega10_I2CLineID_DDCVGA:
  312. *scl = Vega10_I2C_DDCVGACLK;
  313. *sda = Vega10_I2C_DDCVGADATA;
  314. break;
  315. default:
  316. *scl = 0;
  317. *sda = 0;
  318. break;
  319. }
  320. }
  321. static int get_tdp_table(
  322. struct pp_hwmgr *hwmgr,
  323. struct phm_tdp_table **info_tdp_table,
  324. const Vega10_PPTable_Generic_SubTable_Header *table)
  325. {
  326. uint32_t table_size;
  327. struct phm_tdp_table *tdp_table;
  328. uint8_t scl;
  329. uint8_t sda;
  330. const ATOM_Vega10_PowerTune_Table *power_tune_table;
  331. const ATOM_Vega10_PowerTune_Table_V2 *power_tune_table_v2;
  332. const ATOM_Vega10_PowerTune_Table_V3 *power_tune_table_v3;
  333. table_size = sizeof(uint32_t) + sizeof(struct phm_tdp_table);
  334. tdp_table = kzalloc(table_size, GFP_KERNEL);
  335. if (!tdp_table)
  336. return -ENOMEM;
  337. if (table->ucRevId == 5) {
  338. power_tune_table = (ATOM_Vega10_PowerTune_Table *)table;
  339. tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table->usSocketPowerLimit);
  340. tdp_table->usTDC = le16_to_cpu(power_tune_table->usTdcLimit);
  341. tdp_table->usEDCLimit = le16_to_cpu(power_tune_table->usEdcLimit);
  342. tdp_table->usSoftwareShutdownTemp =
  343. le16_to_cpu(power_tune_table->usSoftwareShutdownTemp);
  344. tdp_table->usTemperatureLimitTedge =
  345. le16_to_cpu(power_tune_table->usTemperatureLimitTedge);
  346. tdp_table->usTemperatureLimitHotspot =
  347. le16_to_cpu(power_tune_table->usTemperatureLimitHotSpot);
  348. tdp_table->usTemperatureLimitLiquid1 =
  349. le16_to_cpu(power_tune_table->usTemperatureLimitLiquid1);
  350. tdp_table->usTemperatureLimitLiquid2 =
  351. le16_to_cpu(power_tune_table->usTemperatureLimitLiquid2);
  352. tdp_table->usTemperatureLimitHBM =
  353. le16_to_cpu(power_tune_table->usTemperatureLimitHBM);
  354. tdp_table->usTemperatureLimitVrVddc =
  355. le16_to_cpu(power_tune_table->usTemperatureLimitVrSoc);
  356. tdp_table->usTemperatureLimitVrMvdd =
  357. le16_to_cpu(power_tune_table->usTemperatureLimitVrMem);
  358. tdp_table->usTemperatureLimitPlx =
  359. le16_to_cpu(power_tune_table->usTemperatureLimitPlx);
  360. tdp_table->ucLiquid1_I2C_address = power_tune_table->ucLiquid1_I2C_address;
  361. tdp_table->ucLiquid2_I2C_address = power_tune_table->ucLiquid2_I2C_address;
  362. tdp_table->ucLiquid_I2C_Line = power_tune_table->ucLiquid_I2C_LineSCL;
  363. tdp_table->ucLiquid_I2C_LineSDA = power_tune_table->ucLiquid_I2C_LineSDA;
  364. tdp_table->ucVr_I2C_address = power_tune_table->ucVr_I2C_address;
  365. tdp_table->ucVr_I2C_Line = power_tune_table->ucVr_I2C_LineSCL;
  366. tdp_table->ucVr_I2C_LineSDA = power_tune_table->ucVr_I2C_LineSDA;
  367. tdp_table->ucPlx_I2C_address = power_tune_table->ucPlx_I2C_address;
  368. tdp_table->ucPlx_I2C_Line = power_tune_table->ucPlx_I2C_LineSCL;
  369. tdp_table->ucPlx_I2C_LineSDA = power_tune_table->ucPlx_I2C_LineSDA;
  370. hwmgr->platform_descriptor.LoadLineSlope = le16_to_cpu(power_tune_table->usLoadLineResistance);
  371. } else if (table->ucRevId == 6) {
  372. power_tune_table_v2 = (ATOM_Vega10_PowerTune_Table_V2 *)table;
  373. tdp_table->usMaximumPowerDeliveryLimit = le16_to_cpu(power_tune_table_v2->usSocketPowerLimit);
  374. tdp_table->usTDC = le16_to_cpu(power_tune_table_v2->usTdcLimit);
  375. tdp_table->usEDCLimit = le16_to_cpu(power_tune_table_v2->usEdcLimit);
  376. tdp_table->usSoftwareShutdownTemp =
  377. le16_to_cpu(power_tune_table_v2->usSoftwareShutdownTemp);
  378. tdp_table->usTemperatureLimitTedge =
  379. le16_to_cpu(power_tune_table_v2->usTemperatureLimitTedge);
  380. tdp_table->usTemperatureLimitHotspot =
  381. le16_to_cpu(power_tune_table_v2->usTemperatureLimitHotSpot);
  382. tdp_table->usTemperatureLimitLiquid1 =
  383. le16_to_cpu(power_tune_table_v2->usTemperatureLimitLiquid1);
  384. tdp_table->usTemperatureLimitLiquid2 =
  385. le16_to_cpu(power_tune_table_v2->usTemperatureLimitLiquid2);
  386. tdp_table->usTemperatureLimitHBM =
  387. le16_to_cpu(power_tune_table_v2->usTemperatureLimitHBM);
  388. tdp_table->usTemperatureLimitVrVddc =
  389. le16_to_cpu(power_tune_table_v2->usTemperatureLimitVrSoc);
  390. tdp_table->usTemperatureLimitVrMvdd =
  391. le16_to_cpu(power_tune_table_v2->usTemperatureLimitVrMem);
  392. tdp_table->usTemperatureLimitPlx =
  393. le16_to_cpu(power_tune_table_v2->usTemperatureLimitPlx);
  394. tdp_table->ucLiquid1_I2C_address = power_tune_table_v2->ucLiquid1_I2C_address;
  395. tdp_table->ucLiquid2_I2C_address = power_tune_table_v2->ucLiquid2_I2C_address;
  396. get_scl_sda_value(power_tune_table_v2->ucLiquid_I2C_Line, &scl, &sda);
  397. tdp_table->ucLiquid_I2C_Line = scl;
  398. tdp_table->ucLiquid_I2C_LineSDA = sda;
  399. tdp_table->ucVr_I2C_address = power_tune_table_v2->ucVr_I2C_address;
  400. get_scl_sda_value(power_tune_table_v2->ucVr_I2C_Line, &scl, &sda);
  401. tdp_table->ucVr_I2C_Line = scl;
  402. tdp_table->ucVr_I2C_LineSDA = sda;
  403. tdp_table->ucPlx_I2C_address = power_tune_table_v2->ucPlx_I2C_address;
  404. get_scl_sda_value(power_tune_table_v2->ucPlx_I2C_Line, &scl, &sda);
  405. tdp_table->ucPlx_I2C_Line = scl;
  406. tdp_table->ucPlx_I2C_LineSDA = sda;
  407. hwmgr->platform_descriptor.LoadLineSlope =
  408. le16_to_cpu(power_tune_table_v2->usLoadLineResistance);
  409. } else {
  410. power_tune_table_v3 = (ATOM_Vega10_PowerTune_Table_V3 *)table;
  411. tdp_table->usMaximumPowerDeliveryLimit = power_tune_table_v3->usSocketPowerLimit;
  412. tdp_table->usTDC = power_tune_table_v3->usTdcLimit;
  413. tdp_table->usEDCLimit = power_tune_table_v3->usEdcLimit;
  414. tdp_table->usSoftwareShutdownTemp = power_tune_table_v3->usSoftwareShutdownTemp;
  415. tdp_table->usTemperatureLimitTedge = power_tune_table_v3->usTemperatureLimitTedge;
  416. tdp_table->usTemperatureLimitHotspot = power_tune_table_v3->usTemperatureLimitHotSpot;
  417. tdp_table->usTemperatureLimitLiquid1 = power_tune_table_v3->usTemperatureLimitLiquid1;
  418. tdp_table->usTemperatureLimitLiquid2 = power_tune_table_v3->usTemperatureLimitLiquid2;
  419. tdp_table->usTemperatureLimitHBM = power_tune_table_v3->usTemperatureLimitHBM;
  420. tdp_table->usTemperatureLimitVrVddc = power_tune_table_v3->usTemperatureLimitVrSoc;
  421. tdp_table->usTemperatureLimitVrMvdd = power_tune_table_v3->usTemperatureLimitVrMem;
  422. tdp_table->usTemperatureLimitPlx = power_tune_table_v3->usTemperatureLimitPlx;
  423. tdp_table->ucLiquid1_I2C_address = power_tune_table_v3->ucLiquid1_I2C_address;
  424. tdp_table->ucLiquid2_I2C_address = power_tune_table_v3->ucLiquid2_I2C_address;
  425. tdp_table->usBoostStartTemperature = power_tune_table_v3->usBoostStartTemperature;
  426. tdp_table->usBoostStopTemperature = power_tune_table_v3->usBoostStopTemperature;
  427. tdp_table->ulBoostClock = power_tune_table_v3->ulBoostClock;
  428. get_scl_sda_value(power_tune_table_v3->ucLiquid_I2C_Line, &scl, &sda);
  429. tdp_table->ucLiquid_I2C_Line = scl;
  430. tdp_table->ucLiquid_I2C_LineSDA = sda;
  431. tdp_table->ucVr_I2C_address = power_tune_table_v3->ucVr_I2C_address;
  432. get_scl_sda_value(power_tune_table_v3->ucVr_I2C_Line, &scl, &sda);
  433. tdp_table->ucVr_I2C_Line = scl;
  434. tdp_table->ucVr_I2C_LineSDA = sda;
  435. tdp_table->ucPlx_I2C_address = power_tune_table_v3->ucPlx_I2C_address;
  436. get_scl_sda_value(power_tune_table_v3->ucPlx_I2C_Line, &scl, &sda);
  437. tdp_table->ucPlx_I2C_Line = scl;
  438. tdp_table->ucPlx_I2C_LineSDA = sda;
  439. hwmgr->platform_descriptor.LoadLineSlope =
  440. le16_to_cpu(power_tune_table_v3->usLoadLineResistance);
  441. }
  442. *info_tdp_table = tdp_table;
  443. return 0;
  444. }
  445. static int get_socclk_voltage_dependency_table(
  446. struct pp_hwmgr *hwmgr,
  447. phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_clk_dep_table,
  448. const ATOM_Vega10_SOCCLK_Dependency_Table *clk_dep_table)
  449. {
  450. uint32_t table_size, i;
  451. phm_ppt_v1_clock_voltage_dependency_table *clk_table;
  452. PP_ASSERT_WITH_CODE(clk_dep_table->ucNumEntries,
  453. "Invalid PowerPlay Table!", return -1);
  454. table_size = sizeof(uint32_t) +
  455. sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
  456. clk_dep_table->ucNumEntries;
  457. clk_table = kzalloc(table_size, GFP_KERNEL);
  458. if (!clk_table)
  459. return -ENOMEM;
  460. clk_table->count = (uint32_t)clk_dep_table->ucNumEntries;
  461. for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
  462. clk_table->entries[i].vddInd =
  463. clk_dep_table->entries[i].ucVddInd;
  464. clk_table->entries[i].clk =
  465. le32_to_cpu(clk_dep_table->entries[i].ulClk);
  466. }
  467. *pp_vega10_clk_dep_table = clk_table;
  468. return 0;
  469. }
  470. static int get_mclk_voltage_dependency_table(
  471. struct pp_hwmgr *hwmgr,
  472. phm_ppt_v1_clock_voltage_dependency_table **pp_vega10_mclk_dep_table,
  473. const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table)
  474. {
  475. uint32_t table_size, i;
  476. phm_ppt_v1_clock_voltage_dependency_table *mclk_table;
  477. PP_ASSERT_WITH_CODE(mclk_dep_table->ucNumEntries,
  478. "Invalid PowerPlay Table!", return -1);
  479. table_size = sizeof(uint32_t) +
  480. sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
  481. mclk_dep_table->ucNumEntries;
  482. mclk_table = kzalloc(table_size, GFP_KERNEL);
  483. if (!mclk_table)
  484. return -ENOMEM;
  485. mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries;
  486. for (i = 0; i < mclk_dep_table->ucNumEntries; i++) {
  487. mclk_table->entries[i].vddInd =
  488. mclk_dep_table->entries[i].ucVddInd;
  489. mclk_table->entries[i].vddciInd =
  490. mclk_dep_table->entries[i].ucVddciInd;
  491. mclk_table->entries[i].mvddInd =
  492. mclk_dep_table->entries[i].ucVddMemInd;
  493. mclk_table->entries[i].clk =
  494. le32_to_cpu(mclk_dep_table->entries[i].ulMemClk);
  495. }
  496. *pp_vega10_mclk_dep_table = mclk_table;
  497. return 0;
  498. }
  499. static int get_gfxclk_voltage_dependency_table(
  500. struct pp_hwmgr *hwmgr,
  501. struct phm_ppt_v1_clock_voltage_dependency_table
  502. **pp_vega10_clk_dep_table,
  503. const ATOM_Vega10_GFXCLK_Dependency_Table *clk_dep_table)
  504. {
  505. uint32_t table_size, i;
  506. struct phm_ppt_v1_clock_voltage_dependency_table
  507. *clk_table;
  508. ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2;
  509. PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
  510. "Invalid PowerPlay Table!", return -1);
  511. table_size = sizeof(uint32_t) +
  512. sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
  513. clk_dep_table->ucNumEntries;
  514. clk_table = kzalloc(table_size, GFP_KERNEL);
  515. if (!clk_table)
  516. return -ENOMEM;
  517. clk_table->count = clk_dep_table->ucNumEntries;
  518. if (clk_dep_table->ucRevId == 0) {
  519. for (i = 0; i < clk_table->count; i++) {
  520. clk_table->entries[i].vddInd =
  521. clk_dep_table->entries[i].ucVddInd;
  522. clk_table->entries[i].clk =
  523. le32_to_cpu(clk_dep_table->entries[i].ulClk);
  524. clk_table->entries[i].cks_enable =
  525. (((le16_to_cpu(clk_dep_table->entries[i].usCKSVOffsetandDisable) & 0x8000)
  526. >> 15) == 0) ? 1 : 0;
  527. clk_table->entries[i].cks_voffset =
  528. le16_to_cpu(clk_dep_table->entries[i].usCKSVOffsetandDisable) & 0x7F;
  529. clk_table->entries[i].sclk_offset =
  530. le16_to_cpu(clk_dep_table->entries[i].usAVFSOffset);
  531. }
  532. } else if (clk_dep_table->ucRevId == 1) {
  533. patom_record_v2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)clk_dep_table->entries;
  534. for (i = 0; i < clk_table->count; i++) {
  535. clk_table->entries[i].vddInd =
  536. patom_record_v2->ucVddInd;
  537. clk_table->entries[i].clk =
  538. le32_to_cpu(patom_record_v2->ulClk);
  539. clk_table->entries[i].cks_enable =
  540. (((le16_to_cpu(patom_record_v2->usCKSVOffsetandDisable) & 0x8000)
  541. >> 15) == 0) ? 1 : 0;
  542. clk_table->entries[i].cks_voffset =
  543. le16_to_cpu(patom_record_v2->usCKSVOffsetandDisable) & 0x7F;
  544. clk_table->entries[i].sclk_offset =
  545. le16_to_cpu(patom_record_v2->usAVFSOffset);
  546. patom_record_v2++;
  547. }
  548. } else {
  549. kfree(clk_table);
  550. PP_ASSERT_WITH_CODE(false,
  551. "Unsupported GFXClockDependencyTable Revision!",
  552. return -EINVAL);
  553. }
  554. *pp_vega10_clk_dep_table = clk_table;
  555. return 0;
  556. }
  557. static int get_pix_clk_voltage_dependency_table(
  558. struct pp_hwmgr *hwmgr,
  559. struct phm_ppt_v1_clock_voltage_dependency_table
  560. **pp_vega10_clk_dep_table,
  561. const ATOM_Vega10_PIXCLK_Dependency_Table *clk_dep_table)
  562. {
  563. uint32_t table_size, i;
  564. struct phm_ppt_v1_clock_voltage_dependency_table
  565. *clk_table;
  566. PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
  567. "Invalid PowerPlay Table!", return -1);
  568. table_size = sizeof(uint32_t) +
  569. sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
  570. clk_dep_table->ucNumEntries;
  571. clk_table = kzalloc(table_size, GFP_KERNEL);
  572. if (!clk_table)
  573. return -ENOMEM;
  574. clk_table->count = clk_dep_table->ucNumEntries;
  575. for (i = 0; i < clk_table->count; i++) {
  576. clk_table->entries[i].vddInd =
  577. clk_dep_table->entries[i].ucVddInd;
  578. clk_table->entries[i].clk =
  579. le32_to_cpu(clk_dep_table->entries[i].ulClk);
  580. }
  581. *pp_vega10_clk_dep_table = clk_table;
  582. return 0;
  583. }
  584. static int get_dcefclk_voltage_dependency_table(
  585. struct pp_hwmgr *hwmgr,
  586. struct phm_ppt_v1_clock_voltage_dependency_table
  587. **pp_vega10_clk_dep_table,
  588. const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
  589. {
  590. uint32_t table_size, i;
  591. uint8_t num_entries;
  592. struct phm_ppt_v1_clock_voltage_dependency_table
  593. *clk_table;
  594. uint32_t dev_id;
  595. uint32_t rev_id;
  596. struct amdgpu_device *adev = hwmgr->adev;
  597. PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
  598. "Invalid PowerPlay Table!", return -1);
  599. /*
  600. * workaround needed to add another DPM level for pioneer cards
  601. * as VBIOS is locked down.
  602. * This DPM level was added to support 3DPM monitors @ 4K120Hz
  603. *
  604. */
  605. dev_id = adev->pdev->device;
  606. rev_id = adev->pdev->revision;
  607. if (dev_id == 0x6863 && rev_id == 0 &&
  608. clk_dep_table->entries[clk_dep_table->ucNumEntries - 1].ulClk < 90000)
  609. num_entries = clk_dep_table->ucNumEntries + 1 > NUM_DSPCLK_LEVELS ?
  610. NUM_DSPCLK_LEVELS : clk_dep_table->ucNumEntries + 1;
  611. else
  612. num_entries = clk_dep_table->ucNumEntries;
  613. table_size = sizeof(uint32_t) +
  614. sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
  615. num_entries;
  616. clk_table = kzalloc(table_size, GFP_KERNEL);
  617. if (!clk_table)
  618. return -ENOMEM;
  619. clk_table->count = (uint32_t)num_entries;
  620. for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
  621. clk_table->entries[i].vddInd =
  622. clk_dep_table->entries[i].ucVddInd;
  623. clk_table->entries[i].clk =
  624. le32_to_cpu(clk_dep_table->entries[i].ulClk);
  625. }
  626. if (i < num_entries) {
  627. clk_table->entries[i].vddInd = clk_dep_table->entries[i-1].ucVddInd;
  628. clk_table->entries[i].clk = 90000;
  629. }
  630. *pp_vega10_clk_dep_table = clk_table;
  631. return 0;
  632. }
  633. static int get_pcie_table(struct pp_hwmgr *hwmgr,
  634. struct phm_ppt_v1_pcie_table **vega10_pcie_table,
  635. const Vega10_PPTable_Generic_SubTable_Header *table)
  636. {
  637. uint32_t table_size, i, pcie_count;
  638. struct phm_ppt_v1_pcie_table *pcie_table;
  639. struct phm_ppt_v2_information *table_info =
  640. (struct phm_ppt_v2_information *)(hwmgr->pptable);
  641. const ATOM_Vega10_PCIE_Table *atom_pcie_table =
  642. (ATOM_Vega10_PCIE_Table *)table;
  643. PP_ASSERT_WITH_CODE(atom_pcie_table->ucNumEntries,
  644. "Invalid PowerPlay Table!",
  645. return 0);
  646. table_size = sizeof(uint32_t) +
  647. sizeof(struct phm_ppt_v1_pcie_record) *
  648. atom_pcie_table->ucNumEntries;
  649. pcie_table = kzalloc(table_size, GFP_KERNEL);
  650. if (!pcie_table)
  651. return -ENOMEM;
  652. pcie_count = table_info->vdd_dep_on_sclk->count;
  653. if (atom_pcie_table->ucNumEntries <= pcie_count)
  654. pcie_count = atom_pcie_table->ucNumEntries;
  655. else
  656. pr_info("Number of Pcie Entries exceed the number of"
  657. " GFXCLK Dpm Levels!"
  658. " Disregarding the excess entries...\n");
  659. pcie_table->count = pcie_count;
  660. for (i = 0; i < pcie_count; i++) {
  661. pcie_table->entries[i].gen_speed =
  662. atom_pcie_table->entries[i].ucPCIEGenSpeed;
  663. pcie_table->entries[i].lane_width =
  664. atom_pcie_table->entries[i].ucPCIELaneWidth;
  665. pcie_table->entries[i].pcie_sclk =
  666. atom_pcie_table->entries[i].ulLCLK;
  667. }
  668. *vega10_pcie_table = pcie_table;
  669. return 0;
  670. }
  671. static int get_hard_limits(
  672. struct pp_hwmgr *hwmgr,
  673. struct phm_clock_and_voltage_limits *limits,
  674. const ATOM_Vega10_Hard_Limit_Table *limit_table)
  675. {
  676. PP_ASSERT_WITH_CODE(limit_table->ucNumEntries,
  677. "Invalid PowerPlay Table!", return -1);
  678. /* currently we always take entries[0] parameters */
  679. limits->sclk = le32_to_cpu(limit_table->entries[0].ulSOCCLKLimit);
  680. limits->mclk = le32_to_cpu(limit_table->entries[0].ulMCLKLimit);
  681. limits->gfxclk = le32_to_cpu(limit_table->entries[0].ulGFXCLKLimit);
  682. limits->vddc = le16_to_cpu(limit_table->entries[0].usVddcLimit);
  683. limits->vddci = le16_to_cpu(limit_table->entries[0].usVddciLimit);
  684. limits->vddmem = le16_to_cpu(limit_table->entries[0].usVddMemLimit);
  685. return 0;
  686. }
  687. static int get_valid_clk(
  688. struct pp_hwmgr *hwmgr,
  689. struct phm_clock_array **clk_table,
  690. const phm_ppt_v1_clock_voltage_dependency_table *clk_volt_pp_table)
  691. {
  692. uint32_t table_size, i;
  693. struct phm_clock_array *table;
  694. PP_ASSERT_WITH_CODE(clk_volt_pp_table->count,
  695. "Invalid PowerPlay Table!", return -1);
  696. table_size = sizeof(uint32_t) +
  697. sizeof(uint32_t) * clk_volt_pp_table->count;
  698. table = kzalloc(table_size, GFP_KERNEL);
  699. if (!table)
  700. return -ENOMEM;
  701. table->count = (uint32_t)clk_volt_pp_table->count;
  702. for (i = 0; i < table->count; i++)
  703. table->values[i] = (uint32_t)clk_volt_pp_table->entries[i].clk;
  704. *clk_table = table;
  705. return 0;
  706. }
  707. static int init_powerplay_extended_tables(
  708. struct pp_hwmgr *hwmgr,
  709. const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
  710. {
  711. int result = 0;
  712. struct phm_ppt_v2_information *pp_table_info =
  713. (struct phm_ppt_v2_information *)(hwmgr->pptable);
  714. const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table =
  715. (const ATOM_Vega10_MM_Dependency_Table *)
  716. (((unsigned long) powerplay_table) +
  717. le16_to_cpu(powerplay_table->usMMDependencyTableOffset));
  718. const Vega10_PPTable_Generic_SubTable_Header *power_tune_table =
  719. (const Vega10_PPTable_Generic_SubTable_Header *)
  720. (((unsigned long) powerplay_table) +
  721. le16_to_cpu(powerplay_table->usPowerTuneTableOffset));
  722. const ATOM_Vega10_SOCCLK_Dependency_Table *socclk_dep_table =
  723. (const ATOM_Vega10_SOCCLK_Dependency_Table *)
  724. (((unsigned long) powerplay_table) +
  725. le16_to_cpu(powerplay_table->usSocclkDependencyTableOffset));
  726. const ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table =
  727. (const ATOM_Vega10_GFXCLK_Dependency_Table *)
  728. (((unsigned long) powerplay_table) +
  729. le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset));
  730. const ATOM_Vega10_DCEFCLK_Dependency_Table *dcefclk_dep_table =
  731. (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
  732. (((unsigned long) powerplay_table) +
  733. le16_to_cpu(powerplay_table->usDcefclkDependencyTableOffset));
  734. const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table =
  735. (const ATOM_Vega10_MCLK_Dependency_Table *)
  736. (((unsigned long) powerplay_table) +
  737. le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
  738. const ATOM_Vega10_Hard_Limit_Table *hard_limits =
  739. (const ATOM_Vega10_Hard_Limit_Table *)
  740. (((unsigned long) powerplay_table) +
  741. le16_to_cpu(powerplay_table->usHardLimitTableOffset));
  742. const Vega10_PPTable_Generic_SubTable_Header *pcie_table =
  743. (const Vega10_PPTable_Generic_SubTable_Header *)
  744. (((unsigned long) powerplay_table) +
  745. le16_to_cpu(powerplay_table->usPCIETableOffset));
  746. const ATOM_Vega10_PIXCLK_Dependency_Table *pixclk_dep_table =
  747. (const ATOM_Vega10_PIXCLK_Dependency_Table *)
  748. (((unsigned long) powerplay_table) +
  749. le16_to_cpu(powerplay_table->usPixclkDependencyTableOffset));
  750. const ATOM_Vega10_PHYCLK_Dependency_Table *phyclk_dep_table =
  751. (const ATOM_Vega10_PHYCLK_Dependency_Table *)
  752. (((unsigned long) powerplay_table) +
  753. le16_to_cpu(powerplay_table->usPhyClkDependencyTableOffset));
  754. const ATOM_Vega10_DISPCLK_Dependency_Table *dispclk_dep_table =
  755. (const ATOM_Vega10_DISPCLK_Dependency_Table *)
  756. (((unsigned long) powerplay_table) +
  757. le16_to_cpu(powerplay_table->usDispClkDependencyTableOffset));
  758. pp_table_info->vdd_dep_on_socclk = NULL;
  759. pp_table_info->vdd_dep_on_sclk = NULL;
  760. pp_table_info->vdd_dep_on_mclk = NULL;
  761. pp_table_info->vdd_dep_on_dcefclk = NULL;
  762. pp_table_info->mm_dep_table = NULL;
  763. pp_table_info->tdp_table = NULL;
  764. pp_table_info->vdd_dep_on_pixclk = NULL;
  765. pp_table_info->vdd_dep_on_phyclk = NULL;
  766. pp_table_info->vdd_dep_on_dispclk = NULL;
  767. if (powerplay_table->usMMDependencyTableOffset)
  768. result = get_mm_clock_voltage_table(hwmgr,
  769. &pp_table_info->mm_dep_table,
  770. mm_dependency_table);
  771. if (!result && powerplay_table->usPowerTuneTableOffset)
  772. result = get_tdp_table(hwmgr,
  773. &pp_table_info->tdp_table,
  774. power_tune_table);
  775. if (!result && powerplay_table->usSocclkDependencyTableOffset)
  776. result = get_socclk_voltage_dependency_table(hwmgr,
  777. &pp_table_info->vdd_dep_on_socclk,
  778. socclk_dep_table);
  779. if (!result && powerplay_table->usGfxclkDependencyTableOffset)
  780. result = get_gfxclk_voltage_dependency_table(hwmgr,
  781. &pp_table_info->vdd_dep_on_sclk,
  782. gfxclk_dep_table);
  783. if (!result && powerplay_table->usPixclkDependencyTableOffset)
  784. result = get_pix_clk_voltage_dependency_table(hwmgr,
  785. &pp_table_info->vdd_dep_on_pixclk,
  786. (const ATOM_Vega10_PIXCLK_Dependency_Table*)
  787. pixclk_dep_table);
  788. if (!result && powerplay_table->usPhyClkDependencyTableOffset)
  789. result = get_pix_clk_voltage_dependency_table(hwmgr,
  790. &pp_table_info->vdd_dep_on_phyclk,
  791. (const ATOM_Vega10_PIXCLK_Dependency_Table *)
  792. phyclk_dep_table);
  793. if (!result && powerplay_table->usDispClkDependencyTableOffset)
  794. result = get_pix_clk_voltage_dependency_table(hwmgr,
  795. &pp_table_info->vdd_dep_on_dispclk,
  796. (const ATOM_Vega10_PIXCLK_Dependency_Table *)
  797. dispclk_dep_table);
  798. if (!result && powerplay_table->usDcefclkDependencyTableOffset)
  799. result = get_dcefclk_voltage_dependency_table(hwmgr,
  800. &pp_table_info->vdd_dep_on_dcefclk,
  801. dcefclk_dep_table);
  802. if (!result && powerplay_table->usMclkDependencyTableOffset)
  803. result = get_mclk_voltage_dependency_table(hwmgr,
  804. &pp_table_info->vdd_dep_on_mclk,
  805. mclk_dep_table);
  806. if (!result && powerplay_table->usPCIETableOffset)
  807. result = get_pcie_table(hwmgr,
  808. &pp_table_info->pcie_table,
  809. pcie_table);
  810. if (!result && powerplay_table->usHardLimitTableOffset)
  811. result = get_hard_limits(hwmgr,
  812. &pp_table_info->max_clock_voltage_on_dc,
  813. hard_limits);
  814. hwmgr->dyn_state.max_clock_voltage_on_dc.sclk =
  815. pp_table_info->max_clock_voltage_on_dc.sclk;
  816. hwmgr->dyn_state.max_clock_voltage_on_dc.mclk =
  817. pp_table_info->max_clock_voltage_on_dc.mclk;
  818. hwmgr->dyn_state.max_clock_voltage_on_dc.vddc =
  819. pp_table_info->max_clock_voltage_on_dc.vddc;
  820. hwmgr->dyn_state.max_clock_voltage_on_dc.vddci =
  821. pp_table_info->max_clock_voltage_on_dc.vddci;
  822. if (!result &&
  823. pp_table_info->vdd_dep_on_socclk &&
  824. pp_table_info->vdd_dep_on_socclk->count)
  825. result = get_valid_clk(hwmgr,
  826. &pp_table_info->valid_socclk_values,
  827. pp_table_info->vdd_dep_on_socclk);
  828. if (!result &&
  829. pp_table_info->vdd_dep_on_sclk &&
  830. pp_table_info->vdd_dep_on_sclk->count)
  831. result = get_valid_clk(hwmgr,
  832. &pp_table_info->valid_sclk_values,
  833. pp_table_info->vdd_dep_on_sclk);
  834. if (!result &&
  835. pp_table_info->vdd_dep_on_dcefclk &&
  836. pp_table_info->vdd_dep_on_dcefclk->count)
  837. result = get_valid_clk(hwmgr,
  838. &pp_table_info->valid_dcefclk_values,
  839. pp_table_info->vdd_dep_on_dcefclk);
  840. if (!result &&
  841. pp_table_info->vdd_dep_on_mclk &&
  842. pp_table_info->vdd_dep_on_mclk->count)
  843. result = get_valid_clk(hwmgr,
  844. &pp_table_info->valid_mclk_values,
  845. pp_table_info->vdd_dep_on_mclk);
  846. return result;
  847. }
  848. static int get_vddc_lookup_table(
  849. struct pp_hwmgr *hwmgr,
  850. phm_ppt_v1_voltage_lookup_table **lookup_table,
  851. const ATOM_Vega10_Voltage_Lookup_Table *vddc_lookup_pp_tables,
  852. uint32_t max_levels)
  853. {
  854. uint32_t table_size, i;
  855. phm_ppt_v1_voltage_lookup_table *table;
  856. PP_ASSERT_WITH_CODE((vddc_lookup_pp_tables->ucNumEntries != 0),
  857. "Invalid SOC_VDDD Lookup Table!", return 1);
  858. table_size = sizeof(uint32_t) +
  859. sizeof(phm_ppt_v1_voltage_lookup_record) * max_levels;
  860. table = kzalloc(table_size, GFP_KERNEL);
  861. if (table == NULL)
  862. return -ENOMEM;
  863. table->count = vddc_lookup_pp_tables->ucNumEntries;
  864. for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++)
  865. table->entries[i].us_vdd =
  866. le16_to_cpu(vddc_lookup_pp_tables->entries[i].usVdd);
  867. *lookup_table = table;
  868. return 0;
  869. }
  870. static int init_dpm_2_parameters(
  871. struct pp_hwmgr *hwmgr,
  872. const ATOM_Vega10_POWERPLAYTABLE *powerplay_table)
  873. {
  874. int result = 0;
  875. struct phm_ppt_v2_information *pp_table_info =
  876. (struct phm_ppt_v2_information *)(hwmgr->pptable);
  877. uint32_t disable_power_control = 0;
  878. pp_table_info->us_ulv_voltage_offset =
  879. le16_to_cpu(powerplay_table->usUlvVoltageOffset);
  880. pp_table_info->us_ulv_smnclk_did =
  881. le16_to_cpu(powerplay_table->usUlvSmnclkDid);
  882. pp_table_info->us_ulv_mp1clk_did =
  883. le16_to_cpu(powerplay_table->usUlvMp1clkDid);
  884. pp_table_info->us_ulv_gfxclk_bypass =
  885. le16_to_cpu(powerplay_table->usUlvGfxclkBypass);
  886. pp_table_info->us_gfxclk_slew_rate =
  887. le16_to_cpu(powerplay_table->usGfxclkSlewRate);
  888. pp_table_info->uc_gfx_dpm_voltage_mode =
  889. le16_to_cpu(powerplay_table->ucGfxVoltageMode);
  890. pp_table_info->uc_soc_dpm_voltage_mode =
  891. le16_to_cpu(powerplay_table->ucSocVoltageMode);
  892. pp_table_info->uc_uclk_dpm_voltage_mode =
  893. le16_to_cpu(powerplay_table->ucUclkVoltageMode);
  894. pp_table_info->uc_uvd_dpm_voltage_mode =
  895. le16_to_cpu(powerplay_table->ucUvdVoltageMode);
  896. pp_table_info->uc_vce_dpm_voltage_mode =
  897. le16_to_cpu(powerplay_table->ucVceVoltageMode);
  898. pp_table_info->uc_mp0_dpm_voltage_mode =
  899. le16_to_cpu(powerplay_table->ucMp0VoltageMode);
  900. pp_table_info->uc_dcef_dpm_voltage_mode =
  901. le16_to_cpu(powerplay_table->ucDcefVoltageMode);
  902. pp_table_info->ppm_parameter_table = NULL;
  903. pp_table_info->vddc_lookup_table = NULL;
  904. pp_table_info->vddmem_lookup_table = NULL;
  905. pp_table_info->vddci_lookup_table = NULL;
  906. /* TDP limits */
  907. hwmgr->platform_descriptor.TDPODLimit =
  908. le16_to_cpu(powerplay_table->usPowerControlLimit);
  909. hwmgr->platform_descriptor.TDPAdjustment = 0;
  910. hwmgr->platform_descriptor.VidAdjustment = 0;
  911. hwmgr->platform_descriptor.VidAdjustmentPolarity = 0;
  912. hwmgr->platform_descriptor.VidMinLimit = 0;
  913. hwmgr->platform_descriptor.VidMaxLimit = 1500000;
  914. hwmgr->platform_descriptor.VidStep = 6250;
  915. disable_power_control = 0;
  916. if (!disable_power_control) {
  917. /* enable TDP overdrive (PowerControl) feature as well if supported */
  918. if (hwmgr->platform_descriptor.TDPODLimit)
  919. phm_cap_set(hwmgr->platform_descriptor.platformCaps,
  920. PHM_PlatformCaps_PowerControl);
  921. }
  922. if (powerplay_table->usVddcLookupTableOffset) {
  923. const ATOM_Vega10_Voltage_Lookup_Table *vddc_table =
  924. (ATOM_Vega10_Voltage_Lookup_Table *)
  925. (((unsigned long)powerplay_table) +
  926. le16_to_cpu(powerplay_table->usVddcLookupTableOffset));
  927. result = get_vddc_lookup_table(hwmgr,
  928. &pp_table_info->vddc_lookup_table, vddc_table, 8);
  929. }
  930. if (powerplay_table->usVddmemLookupTableOffset) {
  931. const ATOM_Vega10_Voltage_Lookup_Table *vdd_mem_table =
  932. (ATOM_Vega10_Voltage_Lookup_Table *)
  933. (((unsigned long)powerplay_table) +
  934. le16_to_cpu(powerplay_table->usVddmemLookupTableOffset));
  935. result = get_vddc_lookup_table(hwmgr,
  936. &pp_table_info->vddmem_lookup_table, vdd_mem_table, 4);
  937. }
  938. if (powerplay_table->usVddciLookupTableOffset) {
  939. const ATOM_Vega10_Voltage_Lookup_Table *vddci_table =
  940. (ATOM_Vega10_Voltage_Lookup_Table *)
  941. (((unsigned long)powerplay_table) +
  942. le16_to_cpu(powerplay_table->usVddciLookupTableOffset));
  943. result = get_vddc_lookup_table(hwmgr,
  944. &pp_table_info->vddci_lookup_table, vddci_table, 4);
  945. }
  946. return result;
  947. }
  948. int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr)
  949. {
  950. int result = 0;
  951. const ATOM_Vega10_POWERPLAYTABLE *powerplay_table;
  952. hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v2_information), GFP_KERNEL);
  953. PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL),
  954. "Failed to allocate hwmgr->pptable!", return -ENOMEM);
  955. powerplay_table = get_powerplay_table(hwmgr);
  956. PP_ASSERT_WITH_CODE((powerplay_table != NULL),
  957. "Missing PowerPlay Table!", return -1);
  958. result = check_powerplay_tables(hwmgr, powerplay_table);
  959. PP_ASSERT_WITH_CODE((result == 0),
  960. "check_powerplay_tables failed", return result);
  961. result = set_platform_caps(hwmgr,
  962. le32_to_cpu(powerplay_table->ulPlatformCaps));
  963. PP_ASSERT_WITH_CODE((result == 0),
  964. "set_platform_caps failed", return result);
  965. result = init_thermal_controller(hwmgr, powerplay_table);
  966. PP_ASSERT_WITH_CODE((result == 0),
  967. "init_thermal_controller failed", return result);
  968. result = init_over_drive_limits(hwmgr, powerplay_table);
  969. PP_ASSERT_WITH_CODE((result == 0),
  970. "init_over_drive_limits failed", return result);
  971. result = init_powerplay_extended_tables(hwmgr, powerplay_table);
  972. PP_ASSERT_WITH_CODE((result == 0),
  973. "init_powerplay_extended_tables failed", return result);
  974. result = init_dpm_2_parameters(hwmgr, powerplay_table);
  975. PP_ASSERT_WITH_CODE((result == 0),
  976. "init_dpm_2_parameters failed", return result);
  977. return result;
  978. }
  979. static int vega10_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
  980. {
  981. struct phm_ppt_v2_information *pp_table_info =
  982. (struct phm_ppt_v2_information *)(hwmgr->pptable);
  983. kfree(pp_table_info->vdd_dep_on_sclk);
  984. pp_table_info->vdd_dep_on_sclk = NULL;
  985. kfree(pp_table_info->vdd_dep_on_mclk);
  986. pp_table_info->vdd_dep_on_mclk = NULL;
  987. kfree(pp_table_info->valid_mclk_values);
  988. pp_table_info->valid_mclk_values = NULL;
  989. kfree(pp_table_info->valid_sclk_values);
  990. pp_table_info->valid_sclk_values = NULL;
  991. kfree(pp_table_info->vddc_lookup_table);
  992. pp_table_info->vddc_lookup_table = NULL;
  993. kfree(pp_table_info->vddmem_lookup_table);
  994. pp_table_info->vddmem_lookup_table = NULL;
  995. kfree(pp_table_info->vddci_lookup_table);
  996. pp_table_info->vddci_lookup_table = NULL;
  997. kfree(pp_table_info->ppm_parameter_table);
  998. pp_table_info->ppm_parameter_table = NULL;
  999. kfree(pp_table_info->mm_dep_table);
  1000. pp_table_info->mm_dep_table = NULL;
  1001. kfree(pp_table_info->cac_dtp_table);
  1002. pp_table_info->cac_dtp_table = NULL;
  1003. kfree(hwmgr->dyn_state.cac_dtp_table);
  1004. hwmgr->dyn_state.cac_dtp_table = NULL;
  1005. kfree(pp_table_info->tdp_table);
  1006. pp_table_info->tdp_table = NULL;
  1007. kfree(hwmgr->pptable);
  1008. hwmgr->pptable = NULL;
  1009. return 0;
  1010. }
  1011. const struct pp_table_func vega10_pptable_funcs = {
  1012. .pptable_init = vega10_pp_tables_initialize,
  1013. .pptable_fini = vega10_pp_tables_uninitialize,
  1014. };
  1015. int vega10_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr)
  1016. {
  1017. const ATOM_Vega10_State_Array *state_arrays;
  1018. const ATOM_Vega10_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
  1019. PP_ASSERT_WITH_CODE((pp_table != NULL),
  1020. "Missing PowerPlay Table!", return -1);
  1021. PP_ASSERT_WITH_CODE((pp_table->sHeader.format_revision >=
  1022. ATOM_Vega10_TABLE_REVISION_VEGA10),
  1023. "Incorrect PowerPlay table revision!", return -1);
  1024. state_arrays = (ATOM_Vega10_State_Array *)(((unsigned long)pp_table) +
  1025. le16_to_cpu(pp_table->usStateArrayOffset));
  1026. return (uint32_t)(state_arrays->ucNumEntries);
  1027. }
  1028. static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr,
  1029. uint16_t classification, uint16_t classification2)
  1030. {
  1031. uint32_t result = 0;
  1032. if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT)
  1033. result |= PP_StateClassificationFlag_Boot;
  1034. if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL)
  1035. result |= PP_StateClassificationFlag_Thermal;
  1036. if (classification & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
  1037. result |= PP_StateClassificationFlag_LimitedPowerSource;
  1038. if (classification & ATOM_PPLIB_CLASSIFICATION_REST)
  1039. result |= PP_StateClassificationFlag_Rest;
  1040. if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED)
  1041. result |= PP_StateClassificationFlag_Forced;
  1042. if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI)
  1043. result |= PP_StateClassificationFlag_ACPI;
  1044. if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
  1045. result |= PP_StateClassificationFlag_LimitedPowerSource_2;
  1046. return result;
  1047. }
  1048. int vega10_get_powerplay_table_entry(struct pp_hwmgr *hwmgr,
  1049. uint32_t entry_index, struct pp_power_state *power_state,
  1050. int (*call_back_func)(struct pp_hwmgr *, void *,
  1051. struct pp_power_state *, void *, uint32_t))
  1052. {
  1053. int result = 0;
  1054. const ATOM_Vega10_State_Array *state_arrays;
  1055. const ATOM_Vega10_State *state_entry;
  1056. const ATOM_Vega10_POWERPLAYTABLE *pp_table =
  1057. get_powerplay_table(hwmgr);
  1058. PP_ASSERT_WITH_CODE(pp_table, "Missing PowerPlay Table!",
  1059. return -1;);
  1060. power_state->classification.bios_index = entry_index;
  1061. if (pp_table->sHeader.format_revision >=
  1062. ATOM_Vega10_TABLE_REVISION_VEGA10) {
  1063. state_arrays = (ATOM_Vega10_State_Array *)
  1064. (((unsigned long)pp_table) +
  1065. le16_to_cpu(pp_table->usStateArrayOffset));
  1066. PP_ASSERT_WITH_CODE(pp_table->usStateArrayOffset > 0,
  1067. "Invalid PowerPlay Table State Array Offset.",
  1068. return -1);
  1069. PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0,
  1070. "Invalid PowerPlay Table State Array.",
  1071. return -1);
  1072. PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries),
  1073. "Invalid PowerPlay Table State Array Entry.",
  1074. return -1);
  1075. state_entry = &(state_arrays->states[entry_index]);
  1076. result = call_back_func(hwmgr, (void *)state_entry, power_state,
  1077. (void *)pp_table,
  1078. make_classification_flags(hwmgr,
  1079. le16_to_cpu(state_entry->usClassification),
  1080. le16_to_cpu(state_entry->usClassification2)));
  1081. }
  1082. if (!result && (power_state->classification.flags &
  1083. PP_StateClassificationFlag_Boot))
  1084. result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware));
  1085. return result;
  1086. }