Linux Audio

Check our new training course

Yocto distribution development and maintenance

Need a Yocto distribution for your embedded project?
Loading...
v6.9.4
  1/*
  2 * Copyright 2015 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 "pp_debug.h"
 25#include <linux/delay.h>
 26#include <linux/kernel.h>
 27#include <linux/slab.h>
 28#include <linux/types.h>
 29#include <linux/pci.h>
 30#include <drm/amdgpu_drm.h>
 31#include "power_state.h"
 32#include "hwmgr.h"
 33#include "ppsmc.h"
 34#include "amd_acpi.h"
 35#include "pp_psm.h"
 36#include "vega10_hwmgr.h"
 37
 38extern const struct pp_smumgr_func ci_smu_funcs;
 39extern const struct pp_smumgr_func smu8_smu_funcs;
 40extern const struct pp_smumgr_func iceland_smu_funcs;
 41extern const struct pp_smumgr_func tonga_smu_funcs;
 42extern const struct pp_smumgr_func fiji_smu_funcs;
 43extern const struct pp_smumgr_func polaris10_smu_funcs;
 44extern const struct pp_smumgr_func vegam_smu_funcs;
 45extern const struct pp_smumgr_func vega10_smu_funcs;
 46extern const struct pp_smumgr_func vega12_smu_funcs;
 47extern const struct pp_smumgr_func smu10_smu_funcs;
 48extern const struct pp_smumgr_func vega20_smu_funcs;
 49
 50extern int smu10_init_function_pointers(struct pp_hwmgr *hwmgr);
 51
 52static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 53static void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr);
 54static int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr);
 55static int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 56static int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 57static int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 58static int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 59
 60
 61static void hwmgr_init_workload_prority(struct pp_hwmgr *hwmgr)
 62{
 63	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
 64	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
 65	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
 66	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 3;
 67	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4;
 68	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
 69
 70	hwmgr->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
 71	hwmgr->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
 72	hwmgr->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;
 73	hwmgr->workload_setting[3] = PP_SMC_POWER_PROFILE_VIDEO;
 74	hwmgr->workload_setting[4] = PP_SMC_POWER_PROFILE_VR;
 75	hwmgr->workload_setting[5] = PP_SMC_POWER_PROFILE_COMPUTE;
 76}
 77
 78int hwmgr_early_init(struct pp_hwmgr *hwmgr)
 79{
 80	struct amdgpu_device *adev;
 81
 82	if (!hwmgr)
 83		return -EINVAL;
 84
 85	hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
 86	hwmgr->pp_table_version = PP_TABLE_V1;
 87	hwmgr->dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
 88	hwmgr->request_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
 89	hwmgr_init_default_caps(hwmgr);
 90	hwmgr_set_user_specify_caps(hwmgr);
 91	hwmgr->fan_ctrl_is_in_default_mode = true;
 92	hwmgr_init_workload_prority(hwmgr);
 93	hwmgr->gfxoff_state_changed_by_workload = false;
 94
 95	adev = hwmgr->adev;
 96
 97	switch (hwmgr->chip_family) {
 98	case AMDGPU_FAMILY_CI:
 99		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
100		hwmgr->smumgr_funcs = &ci_smu_funcs;
101		ci_set_asic_special_caps(hwmgr);
102		hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
103					 PP_ENABLE_GFX_CG_THRU_SMU |
104					 PP_GFXOFF_MASK);
105		hwmgr->pp_table_version = PP_TABLE_V0;
106		hwmgr->od_enabled = false;
107		smu7_init_function_pointers(hwmgr);
108		break;
109	case AMDGPU_FAMILY_CZ:
110		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
111		hwmgr->od_enabled = false;
112		hwmgr->smumgr_funcs = &smu8_smu_funcs;
113		hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
114		smu8_init_function_pointers(hwmgr);
115		break;
116	case AMDGPU_FAMILY_VI:
117		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
118		hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
119		switch (hwmgr->chip_id) {
120		case CHIP_TOPAZ:
121			hwmgr->smumgr_funcs = &iceland_smu_funcs;
122			topaz_set_asic_special_caps(hwmgr);
123			hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
124						PP_ENABLE_GFX_CG_THRU_SMU);
125			hwmgr->pp_table_version = PP_TABLE_V0;
126			hwmgr->od_enabled = false;
127			break;
128		case CHIP_TONGA:
129			hwmgr->smumgr_funcs = &tonga_smu_funcs;
130			tonga_set_asic_special_caps(hwmgr);
131			hwmgr->feature_mask &= ~PP_VBI_TIME_SUPPORT_MASK;
132			break;
133		case CHIP_FIJI:
134			hwmgr->smumgr_funcs = &fiji_smu_funcs;
135			fiji_set_asic_special_caps(hwmgr);
136			hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
137						PP_ENABLE_GFX_CG_THRU_SMU);
138			break;
139		case CHIP_POLARIS11:
140		case CHIP_POLARIS10:
141		case CHIP_POLARIS12:
142			hwmgr->smumgr_funcs = &polaris10_smu_funcs;
143			polaris_set_asic_special_caps(hwmgr);
144			hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
145			break;
146		case CHIP_VEGAM:
147			hwmgr->smumgr_funcs = &vegam_smu_funcs;
148			polaris_set_asic_special_caps(hwmgr);
149			hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
150			break;
151		default:
152			return -EINVAL;
153		}
154		smu7_init_function_pointers(hwmgr);
155		break;
156	case AMDGPU_FAMILY_AI:
157		switch (hwmgr->chip_id) {
158		case CHIP_VEGA10:
159			adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
160			hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
161			hwmgr->smumgr_funcs = &vega10_smu_funcs;
162			vega10_hwmgr_init(hwmgr);
163			break;
164		case CHIP_VEGA12:
165			hwmgr->smumgr_funcs = &vega12_smu_funcs;
166			vega12_hwmgr_init(hwmgr);
167			break;
168		case CHIP_VEGA20:
169			adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
170			hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
171			hwmgr->smumgr_funcs = &vega20_smu_funcs;
172			vega20_hwmgr_init(hwmgr);
173			break;
174		default:
175			return -EINVAL;
176		}
177		break;
178	case AMDGPU_FAMILY_RV:
179		switch (hwmgr->chip_id) {
180		case CHIP_RAVEN:
181			hwmgr->od_enabled = false;
182			hwmgr->smumgr_funcs = &smu10_smu_funcs;
183			smu10_init_function_pointers(hwmgr);
184			break;
185		default:
186			return -EINVAL;
187		}
188		break;
189	default:
190		return -EINVAL;
191	}
192
193	return 0;
194}
195
196int hwmgr_sw_init(struct pp_hwmgr *hwmgr)
197{
198	if (!hwmgr || !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->smu_init)
199		return -EINVAL;
200
201	phm_register_irq_handlers(hwmgr);
202	pr_info("hwmgr_sw_init smu backed is %s\n", hwmgr->smumgr_funcs->name);
203
204	return hwmgr->smumgr_funcs->smu_init(hwmgr);
205}
206
207
208int hwmgr_sw_fini(struct pp_hwmgr *hwmgr)
209{
210	if (hwmgr && hwmgr->smumgr_funcs && hwmgr->smumgr_funcs->smu_fini)
211		hwmgr->smumgr_funcs->smu_fini(hwmgr);
212
213	return 0;
214}
215
216int hwmgr_hw_init(struct pp_hwmgr *hwmgr)
217{
218	int ret = 0;
219
220	hwmgr->pp_one_vf = amdgpu_sriov_is_pp_one_vf((struct amdgpu_device *)hwmgr->adev);
221	hwmgr->pm_en = (amdgpu_dpm && (hwmgr->not_vf || hwmgr->pp_one_vf))
222			? true : false;
223	if (!hwmgr->pm_en)
224		return 0;
225
226	if (!hwmgr->pptable_func ||
227	    !hwmgr->pptable_func->pptable_init ||
228	    !hwmgr->hwmgr_func->backend_init) {
229		hwmgr->pm_en = false;
230		pr_info("dpm not supported \n");
231		return 0;
232	}
233
234	ret = hwmgr->pptable_func->pptable_init(hwmgr);
235	if (ret)
236		goto err;
237
238	((struct amdgpu_device *)hwmgr->adev)->pm.no_fan =
239				hwmgr->thermal_controller.fanInfo.bNoFan;
240
241	ret = hwmgr->hwmgr_func->backend_init(hwmgr);
242	if (ret)
243		goto err1;
244 /* make sure dc limits are valid */
245	if ((hwmgr->dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
246			(hwmgr->dyn_state.max_clock_voltage_on_dc.mclk == 0))
247			hwmgr->dyn_state.max_clock_voltage_on_dc =
248					hwmgr->dyn_state.max_clock_voltage_on_ac;
249
250	ret = psm_init_power_state_table(hwmgr);
251	if (ret)
252		goto err2;
253
254	ret = phm_setup_asic(hwmgr);
255	if (ret)
256		goto err2;
257
258	ret = phm_enable_dynamic_state_management(hwmgr);
259	if (ret)
260		goto err2;
261	ret = phm_start_thermal_controller(hwmgr);
262	ret |= psm_set_performance_states(hwmgr);
263	if (ret)
264		goto err2;
265
266	((struct amdgpu_device *)hwmgr->adev)->pm.dpm_enabled = true;
267
268	return 0;
269err2:
270	if (hwmgr->hwmgr_func->backend_fini)
271		hwmgr->hwmgr_func->backend_fini(hwmgr);
272err1:
273	if (hwmgr->pptable_func->pptable_fini)
274		hwmgr->pptable_func->pptable_fini(hwmgr);
275err:
276	return ret;
277}
278
279int hwmgr_hw_fini(struct pp_hwmgr *hwmgr)
280{
281	if (!hwmgr || !hwmgr->pm_en || !hwmgr->not_vf)
282		return 0;
283
284	phm_stop_thermal_controller(hwmgr);
285	psm_set_boot_states(hwmgr);
286	psm_adjust_power_state_dynamic(hwmgr, true, NULL);
287	phm_disable_dynamic_state_management(hwmgr);
288	phm_disable_clock_power_gatings(hwmgr);
289
290	if (hwmgr->hwmgr_func->backend_fini)
291		hwmgr->hwmgr_func->backend_fini(hwmgr);
292	if (hwmgr->pptable_func->pptable_fini)
293		hwmgr->pptable_func->pptable_fini(hwmgr);
294	return psm_fini_power_state_table(hwmgr);
295}
296
297int hwmgr_suspend(struct pp_hwmgr *hwmgr)
298{
299	int ret = 0;
300
301	if (!hwmgr || !hwmgr->pm_en || !hwmgr->not_vf)
302		return 0;
303
304	phm_disable_smc_firmware_ctf(hwmgr);
305	ret = psm_set_boot_states(hwmgr);
306	if (ret)
307		return ret;
308	ret = psm_adjust_power_state_dynamic(hwmgr, true, NULL);
309	if (ret)
310		return ret;
311	ret = phm_power_down_asic(hwmgr);
312
313	return ret;
314}
315
316int hwmgr_resume(struct pp_hwmgr *hwmgr)
317{
318	int ret = 0;
319
320	if (!hwmgr)
321		return -EINVAL;
322
323	if (!hwmgr->not_vf || !hwmgr->pm_en)
324		return 0;
325
326	ret = phm_setup_asic(hwmgr);
327	if (ret)
328		return ret;
329
330	ret = phm_enable_dynamic_state_management(hwmgr);
331	if (ret)
332		return ret;
333	ret = phm_start_thermal_controller(hwmgr);
334	ret |= psm_set_performance_states(hwmgr);
335	if (ret)
336		return ret;
337
338	ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
339
340	return ret;
341}
342
343static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type  state)
344{
345	switch (state) {
346	case POWER_STATE_TYPE_BATTERY:
347		return PP_StateUILabel_Battery;
348	case POWER_STATE_TYPE_BALANCED:
349		return PP_StateUILabel_Balanced;
350	case POWER_STATE_TYPE_PERFORMANCE:
351		return PP_StateUILabel_Performance;
352	default:
353		return PP_StateUILabel_None;
354	}
355}
356
357int hwmgr_handle_task(struct pp_hwmgr *hwmgr, enum amd_pp_task task_id,
358		enum amd_pm_state_type *user_state)
359{
360	int ret = 0;
361
362	if (hwmgr == NULL)
363		return -EINVAL;
364
365	switch (task_id) {
366	case AMD_PP_TASK_DISPLAY_CONFIG_CHANGE:
367		if (!hwmgr->not_vf)
368			return ret;
369		ret = phm_pre_display_configuration_changed(hwmgr);
370		if (ret)
371			return ret;
372		ret = phm_set_cpu_power_state(hwmgr);
373		if (ret)
374			return ret;
375		ret = psm_set_performance_states(hwmgr);
376		if (ret)
377			return ret;
378		ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
379		break;
380	case AMD_PP_TASK_ENABLE_USER_STATE:
381	{
382		enum PP_StateUILabel requested_ui_label;
383		struct pp_power_state *requested_ps = NULL;
384
385		if (!hwmgr->not_vf)
386			return ret;
387		if (user_state == NULL) {
388			ret = -EINVAL;
389			break;
390		}
391
392		requested_ui_label = power_state_convert(*user_state);
393		ret = psm_set_user_performance_state(hwmgr, requested_ui_label, &requested_ps);
394		if (ret)
395			return ret;
396		ret = psm_adjust_power_state_dynamic(hwmgr, true, requested_ps);
397		break;
398	}
399	case AMD_PP_TASK_COMPLETE_INIT:
400	case AMD_PP_TASK_READJUST_POWER_STATE:
401		ret = psm_adjust_power_state_dynamic(hwmgr, true, NULL);
402		break;
403	default:
404		break;
405	}
406	return ret;
407}
408
409void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr)
410{
411	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
412
413	phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);
414	phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);
415
416#if defined(CONFIG_ACPI)
417	if (amdgpu_acpi_is_pcie_performance_request_supported(hwmgr->adev))
418		phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
419#endif
420
421	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
422		PHM_PlatformCaps_DynamicPatchPowerState);
423
424	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
425		PHM_PlatformCaps_EnableSMU7ThermalManagement);
426
427	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
428			PHM_PlatformCaps_DynamicPowerManagement);
429
430	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
431					PHM_PlatformCaps_SMC);
432
433	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
434					PHM_PlatformCaps_DynamicUVDState);
435
436	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
437						PHM_PlatformCaps_FanSpeedInTableIsRPM);
438	return;
439}
440
441int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr)
442{
443	if (hwmgr->feature_mask & PP_SCLK_DEEP_SLEEP_MASK)
444		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
445			PHM_PlatformCaps_SclkDeepSleep);
446	else
447		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
448			PHM_PlatformCaps_SclkDeepSleep);
449
450	if (hwmgr->feature_mask & PP_POWER_CONTAINMENT_MASK) {
451		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
452			    PHM_PlatformCaps_PowerContainment);
453		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
454			PHM_PlatformCaps_CAC);
455	} else {
456		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
457			    PHM_PlatformCaps_PowerContainment);
458		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
459			PHM_PlatformCaps_CAC);
460	}
461
462	if (hwmgr->feature_mask & PP_OVERDRIVE_MASK)
463		hwmgr->od_enabled = true;
464
465	return 0;
466}
467
468int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr)
469{
470	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
471						PHM_PlatformCaps_EVV);
472	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
473						PHM_PlatformCaps_SQRamping);
474	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
475						PHM_PlatformCaps_RegulatorHot);
476
477	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
478			PHM_PlatformCaps_MemorySpreadSpectrumSupport);
479	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
480			PHM_PlatformCaps_EngineSpreadSpectrumSupport);
481
482	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
483					PHM_PlatformCaps_AutomaticDCTransition);
484
485	if (((hwmgr->chip_id == CHIP_POLARIS11) && !hwmgr->is_kicker) ||
486	    (hwmgr->chip_id == CHIP_POLARIS12))
487		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
488				PHM_PlatformCaps_SPLLShutdownSupport);
489
490	if (hwmgr->chip_id != CHIP_POLARIS11) {
491		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
492							PHM_PlatformCaps_DBRamping);
493		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
494							PHM_PlatformCaps_TDRamping);
495		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
496							PHM_PlatformCaps_TCPRamping);
497	}
498	return 0;
499}
500
501int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr)
502{
503	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
504						PHM_PlatformCaps_EVV);
505	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
506			PHM_PlatformCaps_SQRamping);
507	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
508			PHM_PlatformCaps_DBRamping);
509	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
510			PHM_PlatformCaps_TDRamping);
511	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
512			PHM_PlatformCaps_TCPRamping);
513	return 0;
514}
515
516int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr)
517{
518	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
519						PHM_PlatformCaps_EVV);
520	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
521			PHM_PlatformCaps_SQRamping);
522	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
523			PHM_PlatformCaps_DBRamping);
524	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
525			PHM_PlatformCaps_TDRamping);
526	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
527			PHM_PlatformCaps_TCPRamping);
528
529	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
530		      PHM_PlatformCaps_UVDPowerGating);
531	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
532		      PHM_PlatformCaps_VCEPowerGating);
533	return 0;
534}
535
536int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr)
537{
538	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
539						PHM_PlatformCaps_EVV);
540	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
541			PHM_PlatformCaps_SQRamping);
542	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
543			PHM_PlatformCaps_DBRamping);
544	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
545			PHM_PlatformCaps_TDRamping);
546	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
547			PHM_PlatformCaps_TCPRamping);
548	return 0;
549}
550
551int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr)
552{
553	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
554			PHM_PlatformCaps_SQRamping);
555	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
556			PHM_PlatformCaps_DBRamping);
557	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
558			PHM_PlatformCaps_TDRamping);
559	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
560			PHM_PlatformCaps_TCPRamping);
561	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
562			PHM_PlatformCaps_MemorySpreadSpectrumSupport);
563	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
564			PHM_PlatformCaps_EngineSpreadSpectrumSupport);
565	return 0;
566}
v6.8
  1/*
  2 * Copyright 2015 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 "pp_debug.h"
 25#include <linux/delay.h>
 26#include <linux/kernel.h>
 27#include <linux/slab.h>
 28#include <linux/types.h>
 29#include <linux/pci.h>
 30#include <drm/amdgpu_drm.h>
 31#include "power_state.h"
 32#include "hwmgr.h"
 33#include "ppsmc.h"
 34#include "amd_acpi.h"
 35#include "pp_psm.h"
 36#include "vega10_hwmgr.h"
 37
 38extern const struct pp_smumgr_func ci_smu_funcs;
 39extern const struct pp_smumgr_func smu8_smu_funcs;
 40extern const struct pp_smumgr_func iceland_smu_funcs;
 41extern const struct pp_smumgr_func tonga_smu_funcs;
 42extern const struct pp_smumgr_func fiji_smu_funcs;
 43extern const struct pp_smumgr_func polaris10_smu_funcs;
 44extern const struct pp_smumgr_func vegam_smu_funcs;
 45extern const struct pp_smumgr_func vega10_smu_funcs;
 46extern const struct pp_smumgr_func vega12_smu_funcs;
 47extern const struct pp_smumgr_func smu10_smu_funcs;
 48extern const struct pp_smumgr_func vega20_smu_funcs;
 49
 50extern int smu10_init_function_pointers(struct pp_hwmgr *hwmgr);
 51
 52static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 53static void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr);
 54static int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr);
 55static int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 56static int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 57static int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 58static int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 59
 60
 61static void hwmgr_init_workload_prority(struct pp_hwmgr *hwmgr)
 62{
 63	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
 64	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
 65	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
 66	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 3;
 67	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4;
 68	hwmgr->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
 69
 70	hwmgr->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
 71	hwmgr->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
 72	hwmgr->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;
 73	hwmgr->workload_setting[3] = PP_SMC_POWER_PROFILE_VIDEO;
 74	hwmgr->workload_setting[4] = PP_SMC_POWER_PROFILE_VR;
 75	hwmgr->workload_setting[5] = PP_SMC_POWER_PROFILE_COMPUTE;
 76}
 77
 78int hwmgr_early_init(struct pp_hwmgr *hwmgr)
 79{
 80	struct amdgpu_device *adev;
 81
 82	if (!hwmgr)
 83		return -EINVAL;
 84
 85	hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
 86	hwmgr->pp_table_version = PP_TABLE_V1;
 87	hwmgr->dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
 88	hwmgr->request_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
 89	hwmgr_init_default_caps(hwmgr);
 90	hwmgr_set_user_specify_caps(hwmgr);
 91	hwmgr->fan_ctrl_is_in_default_mode = true;
 92	hwmgr_init_workload_prority(hwmgr);
 93	hwmgr->gfxoff_state_changed_by_workload = false;
 94
 95	adev = hwmgr->adev;
 96
 97	switch (hwmgr->chip_family) {
 98	case AMDGPU_FAMILY_CI:
 99		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
100		hwmgr->smumgr_funcs = &ci_smu_funcs;
101		ci_set_asic_special_caps(hwmgr);
102		hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
103					 PP_ENABLE_GFX_CG_THRU_SMU |
104					 PP_GFXOFF_MASK);
105		hwmgr->pp_table_version = PP_TABLE_V0;
106		hwmgr->od_enabled = false;
107		smu7_init_function_pointers(hwmgr);
108		break;
109	case AMDGPU_FAMILY_CZ:
110		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
111		hwmgr->od_enabled = false;
112		hwmgr->smumgr_funcs = &smu8_smu_funcs;
113		hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
114		smu8_init_function_pointers(hwmgr);
115		break;
116	case AMDGPU_FAMILY_VI:
117		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
118		hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
119		switch (hwmgr->chip_id) {
120		case CHIP_TOPAZ:
121			hwmgr->smumgr_funcs = &iceland_smu_funcs;
122			topaz_set_asic_special_caps(hwmgr);
123			hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
124						PP_ENABLE_GFX_CG_THRU_SMU);
125			hwmgr->pp_table_version = PP_TABLE_V0;
126			hwmgr->od_enabled = false;
127			break;
128		case CHIP_TONGA:
129			hwmgr->smumgr_funcs = &tonga_smu_funcs;
130			tonga_set_asic_special_caps(hwmgr);
131			hwmgr->feature_mask &= ~PP_VBI_TIME_SUPPORT_MASK;
132			break;
133		case CHIP_FIJI:
134			hwmgr->smumgr_funcs = &fiji_smu_funcs;
135			fiji_set_asic_special_caps(hwmgr);
136			hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
137						PP_ENABLE_GFX_CG_THRU_SMU);
138			break;
139		case CHIP_POLARIS11:
140		case CHIP_POLARIS10:
141		case CHIP_POLARIS12:
142			hwmgr->smumgr_funcs = &polaris10_smu_funcs;
143			polaris_set_asic_special_caps(hwmgr);
144			hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
145			break;
146		case CHIP_VEGAM:
147			hwmgr->smumgr_funcs = &vegam_smu_funcs;
148			polaris_set_asic_special_caps(hwmgr);
149			hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
150			break;
151		default:
152			return -EINVAL;
153		}
154		smu7_init_function_pointers(hwmgr);
155		break;
156	case AMDGPU_FAMILY_AI:
157		switch (hwmgr->chip_id) {
158		case CHIP_VEGA10:
159			adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
160			hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
161			hwmgr->smumgr_funcs = &vega10_smu_funcs;
162			vega10_hwmgr_init(hwmgr);
163			break;
164		case CHIP_VEGA12:
165			hwmgr->smumgr_funcs = &vega12_smu_funcs;
166			vega12_hwmgr_init(hwmgr);
167			break;
168		case CHIP_VEGA20:
169			adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
170			hwmgr->feature_mask &= ~PP_GFXOFF_MASK;
171			hwmgr->smumgr_funcs = &vega20_smu_funcs;
172			vega20_hwmgr_init(hwmgr);
173			break;
174		default:
175			return -EINVAL;
176		}
177		break;
178	case AMDGPU_FAMILY_RV:
179		switch (hwmgr->chip_id) {
180		case CHIP_RAVEN:
181			hwmgr->od_enabled = false;
182			hwmgr->smumgr_funcs = &smu10_smu_funcs;
183			smu10_init_function_pointers(hwmgr);
184			break;
185		default:
186			return -EINVAL;
187		}
188		break;
189	default:
190		return -EINVAL;
191	}
192
193	return 0;
194}
195
196int hwmgr_sw_init(struct pp_hwmgr *hwmgr)
197{
198	if (!hwmgr || !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->smu_init)
199		return -EINVAL;
200
201	phm_register_irq_handlers(hwmgr);
202	pr_info("hwmgr_sw_init smu backed is %s\n", hwmgr->smumgr_funcs->name);
203
204	return hwmgr->smumgr_funcs->smu_init(hwmgr);
205}
206
207
208int hwmgr_sw_fini(struct pp_hwmgr *hwmgr)
209{
210	if (hwmgr && hwmgr->smumgr_funcs && hwmgr->smumgr_funcs->smu_fini)
211		hwmgr->smumgr_funcs->smu_fini(hwmgr);
212
213	return 0;
214}
215
216int hwmgr_hw_init(struct pp_hwmgr *hwmgr)
217{
218	int ret = 0;
219
220	hwmgr->pp_one_vf = amdgpu_sriov_is_pp_one_vf((struct amdgpu_device *)hwmgr->adev);
221	hwmgr->pm_en = (amdgpu_dpm && (hwmgr->not_vf || hwmgr->pp_one_vf))
222			? true : false;
223	if (!hwmgr->pm_en)
224		return 0;
225
226	if (!hwmgr->pptable_func ||
227	    !hwmgr->pptable_func->pptable_init ||
228	    !hwmgr->hwmgr_func->backend_init) {
229		hwmgr->pm_en = false;
230		pr_info("dpm not supported \n");
231		return 0;
232	}
233
234	ret = hwmgr->pptable_func->pptable_init(hwmgr);
235	if (ret)
236		goto err;
237
238	((struct amdgpu_device *)hwmgr->adev)->pm.no_fan =
239				hwmgr->thermal_controller.fanInfo.bNoFan;
240
241	ret = hwmgr->hwmgr_func->backend_init(hwmgr);
242	if (ret)
243		goto err1;
244 /* make sure dc limits are valid */
245	if ((hwmgr->dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
246			(hwmgr->dyn_state.max_clock_voltage_on_dc.mclk == 0))
247			hwmgr->dyn_state.max_clock_voltage_on_dc =
248					hwmgr->dyn_state.max_clock_voltage_on_ac;
249
250	ret = psm_init_power_state_table(hwmgr);
251	if (ret)
252		goto err2;
253
254	ret = phm_setup_asic(hwmgr);
255	if (ret)
256		goto err2;
257
258	ret = phm_enable_dynamic_state_management(hwmgr);
259	if (ret)
260		goto err2;
261	ret = phm_start_thermal_controller(hwmgr);
262	ret |= psm_set_performance_states(hwmgr);
263	if (ret)
264		goto err2;
265
266	((struct amdgpu_device *)hwmgr->adev)->pm.dpm_enabled = true;
267
268	return 0;
269err2:
270	if (hwmgr->hwmgr_func->backend_fini)
271		hwmgr->hwmgr_func->backend_fini(hwmgr);
272err1:
273	if (hwmgr->pptable_func->pptable_fini)
274		hwmgr->pptable_func->pptable_fini(hwmgr);
275err:
276	return ret;
277}
278
279int hwmgr_hw_fini(struct pp_hwmgr *hwmgr)
280{
281	if (!hwmgr || !hwmgr->pm_en || !hwmgr->not_vf)
282		return 0;
283
284	phm_stop_thermal_controller(hwmgr);
285	psm_set_boot_states(hwmgr);
286	psm_adjust_power_state_dynamic(hwmgr, true, NULL);
287	phm_disable_dynamic_state_management(hwmgr);
288	phm_disable_clock_power_gatings(hwmgr);
289
290	if (hwmgr->hwmgr_func->backend_fini)
291		hwmgr->hwmgr_func->backend_fini(hwmgr);
292	if (hwmgr->pptable_func->pptable_fini)
293		hwmgr->pptable_func->pptable_fini(hwmgr);
294	return psm_fini_power_state_table(hwmgr);
295}
296
297int hwmgr_suspend(struct pp_hwmgr *hwmgr)
298{
299	int ret = 0;
300
301	if (!hwmgr || !hwmgr->pm_en || !hwmgr->not_vf)
302		return 0;
303
304	phm_disable_smc_firmware_ctf(hwmgr);
305	ret = psm_set_boot_states(hwmgr);
306	if (ret)
307		return ret;
308	ret = psm_adjust_power_state_dynamic(hwmgr, true, NULL);
309	if (ret)
310		return ret;
311	ret = phm_power_down_asic(hwmgr);
312
313	return ret;
314}
315
316int hwmgr_resume(struct pp_hwmgr *hwmgr)
317{
318	int ret = 0;
319
320	if (!hwmgr)
321		return -EINVAL;
322
323	if (!hwmgr->not_vf || !hwmgr->pm_en)
324		return 0;
325
326	ret = phm_setup_asic(hwmgr);
327	if (ret)
328		return ret;
329
330	ret = phm_enable_dynamic_state_management(hwmgr);
331	if (ret)
332		return ret;
333	ret = phm_start_thermal_controller(hwmgr);
334	ret |= psm_set_performance_states(hwmgr);
335	if (ret)
336		return ret;
337
338	ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
339
340	return ret;
341}
342
343static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type  state)
344{
345	switch (state) {
346	case POWER_STATE_TYPE_BATTERY:
347		return PP_StateUILabel_Battery;
348	case POWER_STATE_TYPE_BALANCED:
349		return PP_StateUILabel_Balanced;
350	case POWER_STATE_TYPE_PERFORMANCE:
351		return PP_StateUILabel_Performance;
352	default:
353		return PP_StateUILabel_None;
354	}
355}
356
357int hwmgr_handle_task(struct pp_hwmgr *hwmgr, enum amd_pp_task task_id,
358		enum amd_pm_state_type *user_state)
359{
360	int ret = 0;
361
362	if (hwmgr == NULL)
363		return -EINVAL;
364
365	switch (task_id) {
366	case AMD_PP_TASK_DISPLAY_CONFIG_CHANGE:
367		if (!hwmgr->not_vf)
368			return ret;
369		ret = phm_pre_display_configuration_changed(hwmgr);
370		if (ret)
371			return ret;
372		ret = phm_set_cpu_power_state(hwmgr);
373		if (ret)
374			return ret;
375		ret = psm_set_performance_states(hwmgr);
376		if (ret)
377			return ret;
378		ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
379		break;
380	case AMD_PP_TASK_ENABLE_USER_STATE:
381	{
382		enum PP_StateUILabel requested_ui_label;
383		struct pp_power_state *requested_ps = NULL;
384
385		if (!hwmgr->not_vf)
386			return ret;
387		if (user_state == NULL) {
388			ret = -EINVAL;
389			break;
390		}
391
392		requested_ui_label = power_state_convert(*user_state);
393		ret = psm_set_user_performance_state(hwmgr, requested_ui_label, &requested_ps);
394		if (ret)
395			return ret;
396		ret = psm_adjust_power_state_dynamic(hwmgr, true, requested_ps);
397		break;
398	}
399	case AMD_PP_TASK_COMPLETE_INIT:
400	case AMD_PP_TASK_READJUST_POWER_STATE:
401		ret = psm_adjust_power_state_dynamic(hwmgr, true, NULL);
402		break;
403	default:
404		break;
405	}
406	return ret;
407}
408
409void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr)
410{
411	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
412
413	phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);
414	phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);
415
416#if defined(CONFIG_ACPI)
417	if (amdgpu_acpi_is_pcie_performance_request_supported(hwmgr->adev))
418		phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
419#endif
420
421	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
422		PHM_PlatformCaps_DynamicPatchPowerState);
423
424	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
425		PHM_PlatformCaps_EnableSMU7ThermalManagement);
426
427	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
428			PHM_PlatformCaps_DynamicPowerManagement);
429
430	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
431					PHM_PlatformCaps_SMC);
432
433	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
434					PHM_PlatformCaps_DynamicUVDState);
435
436	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
437						PHM_PlatformCaps_FanSpeedInTableIsRPM);
438	return;
439}
440
441int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr)
442{
443	if (hwmgr->feature_mask & PP_SCLK_DEEP_SLEEP_MASK)
444		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
445			PHM_PlatformCaps_SclkDeepSleep);
446	else
447		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
448			PHM_PlatformCaps_SclkDeepSleep);
449
450	if (hwmgr->feature_mask & PP_POWER_CONTAINMENT_MASK) {
451		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
452			    PHM_PlatformCaps_PowerContainment);
453		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
454			PHM_PlatformCaps_CAC);
455	} else {
456		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
457			    PHM_PlatformCaps_PowerContainment);
458		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
459			PHM_PlatformCaps_CAC);
460	}
461
462	if (hwmgr->feature_mask & PP_OVERDRIVE_MASK)
463		hwmgr->od_enabled = true;
464
465	return 0;
466}
467
468int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr)
469{
470	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
471						PHM_PlatformCaps_EVV);
472	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
473						PHM_PlatformCaps_SQRamping);
474	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
475						PHM_PlatformCaps_RegulatorHot);
476
477	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
478			PHM_PlatformCaps_MemorySpreadSpectrumSupport);
479	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
480			PHM_PlatformCaps_EngineSpreadSpectrumSupport);
481
482	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
483					PHM_PlatformCaps_AutomaticDCTransition);
484
485	if (((hwmgr->chip_id == CHIP_POLARIS11) && !hwmgr->is_kicker) ||
486	    (hwmgr->chip_id == CHIP_POLARIS12))
487		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
488				PHM_PlatformCaps_SPLLShutdownSupport);
489
490	if (hwmgr->chip_id != CHIP_POLARIS11) {
491		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
492							PHM_PlatformCaps_DBRamping);
493		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
494							PHM_PlatformCaps_TDRamping);
495		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
496							PHM_PlatformCaps_TCPRamping);
497	}
498	return 0;
499}
500
501int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr)
502{
503	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
504						PHM_PlatformCaps_EVV);
505	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
506			PHM_PlatformCaps_SQRamping);
507	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
508			PHM_PlatformCaps_DBRamping);
509	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
510			PHM_PlatformCaps_TDRamping);
511	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
512			PHM_PlatformCaps_TCPRamping);
513	return 0;
514}
515
516int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr)
517{
518	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
519						PHM_PlatformCaps_EVV);
520	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
521			PHM_PlatformCaps_SQRamping);
522	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
523			PHM_PlatformCaps_DBRamping);
524	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
525			PHM_PlatformCaps_TDRamping);
526	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
527			PHM_PlatformCaps_TCPRamping);
528
529	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
530		      PHM_PlatformCaps_UVDPowerGating);
531	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
532		      PHM_PlatformCaps_VCEPowerGating);
533	return 0;
534}
535
536int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr)
537{
538	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
539						PHM_PlatformCaps_EVV);
540	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
541			PHM_PlatformCaps_SQRamping);
542	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
543			PHM_PlatformCaps_DBRamping);
544	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
545			PHM_PlatformCaps_TDRamping);
546	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
547			PHM_PlatformCaps_TCPRamping);
548	return 0;
549}
550
551int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr)
552{
553	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
554			PHM_PlatformCaps_SQRamping);
555	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
556			PHM_PlatformCaps_DBRamping);
557	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
558			PHM_PlatformCaps_TDRamping);
559	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
560			PHM_PlatformCaps_TCPRamping);
561	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
562			PHM_PlatformCaps_MemorySpreadSpectrumSupport);
563	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
564			PHM_PlatformCaps_EngineSpreadSpectrumSupport);
565	return 0;
566}