smu7_clockpowergating.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  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 "smu7_hwmgr.h"
  24. #include "smu7_clockpowergating.h"
  25. #include "smu7_common.h"
  26. static int smu7_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
  27. {
  28. return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
  29. PPSMC_MSG_UVDDPM_Enable :
  30. PPSMC_MSG_UVDDPM_Disable);
  31. }
  32. static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
  33. {
  34. return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
  35. PPSMC_MSG_VCEDPM_Enable :
  36. PPSMC_MSG_VCEDPM_Disable);
  37. }
  38. static int smu7_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable)
  39. {
  40. return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
  41. PPSMC_MSG_SAMUDPM_Enable :
  42. PPSMC_MSG_SAMUDPM_Disable);
  43. }
  44. static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
  45. {
  46. if (!bgate)
  47. smum_update_smc_table(hwmgr, SMU_UVD_TABLE);
  48. return smu7_enable_disable_uvd_dpm(hwmgr, !bgate);
  49. }
  50. static int smu7_update_vce_dpm(struct pp_hwmgr *hwmgr, bool bgate)
  51. {
  52. if (!bgate)
  53. smum_update_smc_table(hwmgr, SMU_VCE_TABLE);
  54. return smu7_enable_disable_vce_dpm(hwmgr, !bgate);
  55. }
  56. static int smu7_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate)
  57. {
  58. if (!bgate)
  59. smum_update_smc_table(hwmgr, SMU_SAMU_TABLE);
  60. return smu7_enable_disable_samu_dpm(hwmgr, !bgate);
  61. }
  62. int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
  63. {
  64. if (phm_cf_want_uvd_power_gating(hwmgr))
  65. return smum_send_msg_to_smc(hwmgr->smumgr,
  66. PPSMC_MSG_UVDPowerOFF);
  67. return 0;
  68. }
  69. static int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
  70. {
  71. if (phm_cf_want_uvd_power_gating(hwmgr)) {
  72. if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
  73. PHM_PlatformCaps_UVDDynamicPowerGating)) {
  74. return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
  75. PPSMC_MSG_UVDPowerON, 1);
  76. } else {
  77. return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
  78. PPSMC_MSG_UVDPowerON, 0);
  79. }
  80. }
  81. return 0;
  82. }
  83. static int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
  84. {
  85. if (phm_cf_want_vce_power_gating(hwmgr))
  86. return smum_send_msg_to_smc(hwmgr->smumgr,
  87. PPSMC_MSG_VCEPowerOFF);
  88. return 0;
  89. }
  90. static int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
  91. {
  92. if (phm_cf_want_vce_power_gating(hwmgr))
  93. return smum_send_msg_to_smc(hwmgr->smumgr,
  94. PPSMC_MSG_VCEPowerON);
  95. return 0;
  96. }
  97. static int smu7_powerdown_samu(struct pp_hwmgr *hwmgr)
  98. {
  99. if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
  100. PHM_PlatformCaps_SamuPowerGating))
  101. return smum_send_msg_to_smc(hwmgr->smumgr,
  102. PPSMC_MSG_SAMPowerOFF);
  103. return 0;
  104. }
  105. static int smu7_powerup_samu(struct pp_hwmgr *hwmgr)
  106. {
  107. if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
  108. PHM_PlatformCaps_SamuPowerGating))
  109. return smum_send_msg_to_smc(hwmgr->smumgr,
  110. PPSMC_MSG_SAMPowerON);
  111. return 0;
  112. }
  113. int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
  114. {
  115. struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
  116. data->uvd_power_gated = false;
  117. data->vce_power_gated = false;
  118. data->samu_power_gated = false;
  119. smu7_powerup_uvd(hwmgr);
  120. smu7_powerup_vce(hwmgr);
  121. smu7_powerup_samu(hwmgr);
  122. return 0;
  123. }
  124. int smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
  125. {
  126. struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
  127. data->uvd_power_gated = bgate;
  128. if (bgate) {
  129. cgs_set_powergating_state(hwmgr->device,
  130. AMD_IP_BLOCK_TYPE_UVD,
  131. AMD_PG_STATE_GATE);
  132. cgs_set_clockgating_state(hwmgr->device,
  133. AMD_IP_BLOCK_TYPE_UVD,
  134. AMD_CG_STATE_GATE);
  135. smu7_update_uvd_dpm(hwmgr, true);
  136. smu7_powerdown_uvd(hwmgr);
  137. } else {
  138. smu7_powerup_uvd(hwmgr);
  139. cgs_set_clockgating_state(hwmgr->device,
  140. AMD_IP_BLOCK_TYPE_UVD,
  141. AMD_CG_STATE_UNGATE);
  142. cgs_set_powergating_state(hwmgr->device,
  143. AMD_IP_BLOCK_TYPE_UVD,
  144. AMD_PG_STATE_UNGATE);
  145. smu7_update_uvd_dpm(hwmgr, false);
  146. }
  147. return 0;
  148. }
  149. int smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
  150. {
  151. struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
  152. data->vce_power_gated = bgate;
  153. if (bgate) {
  154. cgs_set_powergating_state(hwmgr->device,
  155. AMD_IP_BLOCK_TYPE_VCE,
  156. AMD_PG_STATE_GATE);
  157. cgs_set_clockgating_state(hwmgr->device,
  158. AMD_IP_BLOCK_TYPE_VCE,
  159. AMD_CG_STATE_GATE);
  160. smu7_update_vce_dpm(hwmgr, true);
  161. smu7_powerdown_vce(hwmgr);
  162. } else {
  163. smu7_powerup_vce(hwmgr);
  164. cgs_set_clockgating_state(hwmgr->device,
  165. AMD_IP_BLOCK_TYPE_VCE,
  166. AMD_CG_STATE_UNGATE);
  167. cgs_set_powergating_state(hwmgr->device,
  168. AMD_IP_BLOCK_TYPE_VCE,
  169. AMD_PG_STATE_UNGATE);
  170. smu7_update_vce_dpm(hwmgr, false);
  171. }
  172. return 0;
  173. }
  174. int smu7_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate)
  175. {
  176. struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
  177. if (data->samu_power_gated == bgate)
  178. return 0;
  179. data->samu_power_gated = bgate;
  180. if (bgate) {
  181. smu7_update_samu_dpm(hwmgr, true);
  182. smu7_powerdown_samu(hwmgr);
  183. } else {
  184. smu7_powerup_samu(hwmgr);
  185. smu7_update_samu_dpm(hwmgr, false);
  186. }
  187. return 0;
  188. }
  189. int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
  190. const uint32_t *msg_id)
  191. {
  192. PPSMC_Msg msg;
  193. uint32_t value;
  194. if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
  195. return 0;
  196. switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
  197. case PP_GROUP_GFX:
  198. switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
  199. case PP_BLOCK_GFX_CG:
  200. if (PP_STATE_SUPPORT_CG & *msg_id) {
  201. msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
  202. PPSMC_MSG_EnableClockGatingFeature :
  203. PPSMC_MSG_DisableClockGatingFeature;
  204. value = CG_GFX_CGCG_MASK;
  205. if (smum_send_msg_to_smc_with_parameter(
  206. hwmgr->smumgr, msg, value))
  207. return -EINVAL;
  208. }
  209. if (PP_STATE_SUPPORT_LS & *msg_id) {
  210. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
  211. ? PPSMC_MSG_EnableClockGatingFeature
  212. : PPSMC_MSG_DisableClockGatingFeature;
  213. value = CG_GFX_CGLS_MASK;
  214. if (smum_send_msg_to_smc_with_parameter(
  215. hwmgr->smumgr, msg, value))
  216. return -EINVAL;
  217. }
  218. break;
  219. case PP_BLOCK_GFX_3D:
  220. if (PP_STATE_SUPPORT_CG & *msg_id) {
  221. msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
  222. PPSMC_MSG_EnableClockGatingFeature :
  223. PPSMC_MSG_DisableClockGatingFeature;
  224. value = CG_GFX_3DCG_MASK;
  225. if (smum_send_msg_to_smc_with_parameter(
  226. hwmgr->smumgr, msg, value))
  227. return -EINVAL;
  228. }
  229. if (PP_STATE_SUPPORT_LS & *msg_id) {
  230. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
  231. PPSMC_MSG_EnableClockGatingFeature :
  232. PPSMC_MSG_DisableClockGatingFeature;
  233. value = CG_GFX_3DLS_MASK;
  234. if (smum_send_msg_to_smc_with_parameter(
  235. hwmgr->smumgr, msg, value))
  236. return -EINVAL;
  237. }
  238. break;
  239. case PP_BLOCK_GFX_RLC:
  240. if (PP_STATE_SUPPORT_LS & *msg_id) {
  241. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
  242. PPSMC_MSG_EnableClockGatingFeature :
  243. PPSMC_MSG_DisableClockGatingFeature;
  244. value = CG_GFX_RLC_LS_MASK;
  245. if (smum_send_msg_to_smc_with_parameter(
  246. hwmgr->smumgr, msg, value))
  247. return -EINVAL;
  248. }
  249. break;
  250. case PP_BLOCK_GFX_CP:
  251. if (PP_STATE_SUPPORT_LS & *msg_id) {
  252. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
  253. PPSMC_MSG_EnableClockGatingFeature :
  254. PPSMC_MSG_DisableClockGatingFeature;
  255. value = CG_GFX_CP_LS_MASK;
  256. if (smum_send_msg_to_smc_with_parameter(
  257. hwmgr->smumgr, msg, value))
  258. return -EINVAL;
  259. }
  260. break;
  261. case PP_BLOCK_GFX_MG:
  262. if (PP_STATE_SUPPORT_CG & *msg_id) {
  263. msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
  264. PPSMC_MSG_EnableClockGatingFeature :
  265. PPSMC_MSG_DisableClockGatingFeature;
  266. value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
  267. CG_GFX_OTHERS_MGCG_MASK);
  268. if (smum_send_msg_to_smc_with_parameter(
  269. hwmgr->smumgr, msg, value))
  270. return -EINVAL;
  271. }
  272. break;
  273. default:
  274. return -EINVAL;
  275. }
  276. break;
  277. case PP_GROUP_SYS:
  278. switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
  279. case PP_BLOCK_SYS_BIF:
  280. if (PP_STATE_SUPPORT_CG & *msg_id) {
  281. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
  282. PPSMC_MSG_EnableClockGatingFeature :
  283. PPSMC_MSG_DisableClockGatingFeature;
  284. value = CG_SYS_BIF_MGCG_MASK;
  285. if (smum_send_msg_to_smc_with_parameter(
  286. hwmgr->smumgr, msg, value))
  287. return -EINVAL;
  288. }
  289. if (PP_STATE_SUPPORT_LS & *msg_id) {
  290. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
  291. PPSMC_MSG_EnableClockGatingFeature :
  292. PPSMC_MSG_DisableClockGatingFeature;
  293. value = CG_SYS_BIF_MGLS_MASK;
  294. if (smum_send_msg_to_smc_with_parameter(
  295. hwmgr->smumgr, msg, value))
  296. return -EINVAL;
  297. }
  298. break;
  299. case PP_BLOCK_SYS_MC:
  300. if (PP_STATE_SUPPORT_CG & *msg_id) {
  301. msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
  302. PPSMC_MSG_EnableClockGatingFeature :
  303. PPSMC_MSG_DisableClockGatingFeature;
  304. value = CG_SYS_MC_MGCG_MASK;
  305. if (smum_send_msg_to_smc_with_parameter(
  306. hwmgr->smumgr, msg, value))
  307. return -EINVAL;
  308. }
  309. if (PP_STATE_SUPPORT_LS & *msg_id) {
  310. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
  311. PPSMC_MSG_EnableClockGatingFeature :
  312. PPSMC_MSG_DisableClockGatingFeature;
  313. value = CG_SYS_MC_MGLS_MASK;
  314. if (smum_send_msg_to_smc_with_parameter(
  315. hwmgr->smumgr, msg, value))
  316. return -EINVAL;
  317. }
  318. break;
  319. case PP_BLOCK_SYS_DRM:
  320. if (PP_STATE_SUPPORT_CG & *msg_id) {
  321. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
  322. PPSMC_MSG_EnableClockGatingFeature :
  323. PPSMC_MSG_DisableClockGatingFeature;
  324. value = CG_SYS_DRM_MGCG_MASK;
  325. if (smum_send_msg_to_smc_with_parameter(
  326. hwmgr->smumgr, msg, value))
  327. return -EINVAL;
  328. }
  329. if (PP_STATE_SUPPORT_LS & *msg_id) {
  330. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
  331. PPSMC_MSG_EnableClockGatingFeature :
  332. PPSMC_MSG_DisableClockGatingFeature;
  333. value = CG_SYS_DRM_MGLS_MASK;
  334. if (smum_send_msg_to_smc_with_parameter(
  335. hwmgr->smumgr, msg, value))
  336. return -EINVAL;
  337. }
  338. break;
  339. case PP_BLOCK_SYS_HDP:
  340. if (PP_STATE_SUPPORT_CG & *msg_id) {
  341. msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
  342. PPSMC_MSG_EnableClockGatingFeature :
  343. PPSMC_MSG_DisableClockGatingFeature;
  344. value = CG_SYS_HDP_MGCG_MASK;
  345. if (smum_send_msg_to_smc_with_parameter(
  346. hwmgr->smumgr, msg, value))
  347. return -EINVAL;
  348. }
  349. if (PP_STATE_SUPPORT_LS & *msg_id) {
  350. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
  351. PPSMC_MSG_EnableClockGatingFeature :
  352. PPSMC_MSG_DisableClockGatingFeature;
  353. value = CG_SYS_HDP_MGLS_MASK;
  354. if (smum_send_msg_to_smc_with_parameter(
  355. hwmgr->smumgr, msg, value))
  356. return -EINVAL;
  357. }
  358. break;
  359. case PP_BLOCK_SYS_SDMA:
  360. if (PP_STATE_SUPPORT_CG & *msg_id) {
  361. msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
  362. PPSMC_MSG_EnableClockGatingFeature :
  363. PPSMC_MSG_DisableClockGatingFeature;
  364. value = CG_SYS_SDMA_MGCG_MASK;
  365. if (smum_send_msg_to_smc_with_parameter(
  366. hwmgr->smumgr, msg, value))
  367. return -EINVAL;
  368. }
  369. if (PP_STATE_SUPPORT_LS & *msg_id) {
  370. msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
  371. PPSMC_MSG_EnableClockGatingFeature :
  372. PPSMC_MSG_DisableClockGatingFeature;
  373. value = CG_SYS_SDMA_MGLS_MASK;
  374. if (smum_send_msg_to_smc_with_parameter(
  375. hwmgr->smumgr, msg, value))
  376. return -EINVAL;
  377. }
  378. break;
  379. case PP_BLOCK_SYS_ROM:
  380. if (PP_STATE_SUPPORT_CG & *msg_id) {
  381. msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
  382. PPSMC_MSG_EnableClockGatingFeature :
  383. PPSMC_MSG_DisableClockGatingFeature;
  384. value = CG_SYS_ROM_MASK;
  385. if (smum_send_msg_to_smc_with_parameter(
  386. hwmgr->smumgr, msg, value))
  387. return -EINVAL;
  388. }
  389. break;
  390. default:
  391. return -EINVAL;
  392. }
  393. break;
  394. default:
  395. return -EINVAL;
  396. }
  397. return 0;
  398. }
  399. /* This function is for Polaris11 only for now,
  400. * Powerplay will only control the static per CU Power Gating.
  401. * Dynamic per CU Power Gating will be done in gfx.
  402. */
  403. int smu7_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable)
  404. {
  405. struct cgs_system_info sys_info = {0};
  406. uint32_t active_cus;
  407. int result;
  408. sys_info.size = sizeof(struct cgs_system_info);
  409. sys_info.info_id = CGS_SYSTEM_INFO_GFX_CU_INFO;
  410. result = cgs_query_system_info(hwmgr->device, &sys_info);
  411. if (result)
  412. return -EINVAL;
  413. active_cus = sys_info.value;
  414. if (enable)
  415. return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
  416. PPSMC_MSG_GFX_CU_PG_ENABLE, active_cus);
  417. else
  418. return smum_send_msg_to_smc(hwmgr->smumgr,
  419. PPSMC_MSG_GFX_CU_PG_DISABLE);
  420. }