smu7_clockpowergating.c 11 KB

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