File Index
Files and directories
Sign in
FILE

smu7_clockpowergating.c

File preview with syntax highlighting.

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