1f46a221bSXiaojian Du /*
2f46a221bSXiaojian Du  * Copyright 2020 Advanced Micro Devices, Inc.
3f46a221bSXiaojian Du  *
4f46a221bSXiaojian Du  * Permission is hereby granted, free of charge, to any person obtaining a
5f46a221bSXiaojian Du  * copy of this software and associated documentation files (the "Software"),
6f46a221bSXiaojian Du  * to deal in the Software without restriction, including without limitation
7f46a221bSXiaojian Du  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f46a221bSXiaojian Du  * and/or sell copies of the Software, and to permit persons to whom the
9f46a221bSXiaojian Du  * Software is furnished to do so, subject to the following conditions:
10f46a221bSXiaojian Du  *
11f46a221bSXiaojian Du  * The above copyright notice and this permission notice shall be included in
12f46a221bSXiaojian Du  * all copies or substantial portions of the Software.
13f46a221bSXiaojian Du  *
14f46a221bSXiaojian Du  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f46a221bSXiaojian Du  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f46a221bSXiaojian Du  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17f46a221bSXiaojian Du  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18f46a221bSXiaojian Du  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19f46a221bSXiaojian Du  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20f46a221bSXiaojian Du  * OTHER DEALINGS IN THE SOFTWARE.
21f46a221bSXiaojian Du  *
22f46a221bSXiaojian Du  */
23f46a221bSXiaojian Du 
24f46a221bSXiaojian Du #define SWSMU_CODE_LAYER_L2
25f46a221bSXiaojian Du 
26f46a221bSXiaojian Du #include "amdgpu.h"
27f46a221bSXiaojian Du #include "amdgpu_smu.h"
28f46a221bSXiaojian Du #include "smu_v11_0.h"
29f46a221bSXiaojian Du #include "smu11_driver_if_vangogh.h"
30f46a221bSXiaojian Du #include "vangogh_ppt.h"
31f46a221bSXiaojian Du #include "smu_v11_5_ppsmc.h"
32f46a221bSXiaojian Du #include "smu_v11_5_pmfw.h"
33f46a221bSXiaojian Du #include "smu_cmn.h"
34eefdf047SJinzhou Su #include "soc15_common.h"
35eefdf047SJinzhou Su #include "asic_reg/gc/gc_10_3_0_offset.h"
36eefdf047SJinzhou Su #include "asic_reg/gc/gc_10_3_0_sh_mask.h"
37f46a221bSXiaojian Du 
38f46a221bSXiaojian Du /*
39f46a221bSXiaojian Du  * DO NOT use these for err/warn/info/debug messages.
40f46a221bSXiaojian Du  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
41f46a221bSXiaojian Du  * They are more MGPU friendly.
42f46a221bSXiaojian Du  */
43f46a221bSXiaojian Du #undef pr_err
44f46a221bSXiaojian Du #undef pr_warn
45f46a221bSXiaojian Du #undef pr_info
46f46a221bSXiaojian Du #undef pr_debug
47f46a221bSXiaojian Du 
48f46a221bSXiaojian Du #define FEATURE_MASK(feature) (1ULL << feature)
49f46a221bSXiaojian Du #define SMC_DPM_FEATURE ( \
50f46a221bSXiaojian Du 	FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \
51f46a221bSXiaojian Du 	FEATURE_MASK(FEATURE_VCN_DPM_BIT)	 | \
52f46a221bSXiaojian Du 	FEATURE_MASK(FEATURE_FCLK_DPM_BIT)	 | \
53f46a221bSXiaojian Du 	FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT)	 | \
54f46a221bSXiaojian Du 	FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT)	 | \
55f46a221bSXiaojian Du 	FEATURE_MASK(FEATURE_LCLK_DPM_BIT)	 | \
56f46a221bSXiaojian Du 	FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT)	 | \
57f46a221bSXiaojian Du 	FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \
58271ab489SXiaojian Du 	FEATURE_MASK(FEATURE_GFX_DPM_BIT))
59f46a221bSXiaojian Du 
60f46a221bSXiaojian Du static struct cmn2asic_msg_mapping vangogh_message_map[SMU_MSG_MAX_COUNT] = {
61271ab489SXiaojian Du 	MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage,			0),
62271ab489SXiaojian Du 	MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetSmuVersion,		0),
63271ab489SXiaojian Du 	MSG_MAP(GetDriverIfVersion,             PPSMC_MSG_GetDriverIfVersion,	0),
64271ab489SXiaojian Du 	MSG_MAP(EnableGfxOff,                   PPSMC_MSG_EnableGfxOff,			0),
65271ab489SXiaojian Du 	MSG_MAP(DisallowGfxOff,                 PPSMC_MSG_DisableGfxOff,		0),
66271ab489SXiaojian Du 	MSG_MAP(PowerDownIspByTile,             PPSMC_MSG_PowerDownIspByTile,	0),
67271ab489SXiaojian Du 	MSG_MAP(PowerUpIspByTile,               PPSMC_MSG_PowerUpIspByTile,		0),
68271ab489SXiaojian Du 	MSG_MAP(PowerDownVcn,                   PPSMC_MSG_PowerDownVcn,			0),
69271ab489SXiaojian Du 	MSG_MAP(PowerUpVcn,                     PPSMC_MSG_PowerUpVcn,			0),
70a0f55287SXiaomeng Hou 	MSG_MAP(RlcPowerNotify,                 PPSMC_MSG_RlcPowerNotify,		0),
71271ab489SXiaojian Du 	MSG_MAP(SetHardMinVcn,                  PPSMC_MSG_SetHardMinVcn,		0),
72271ab489SXiaojian Du 	MSG_MAP(SetSoftMinGfxclk,               PPSMC_MSG_SetSoftMinGfxclk,		0),
73271ab489SXiaojian Du 	MSG_MAP(ActiveProcessNotify,            PPSMC_MSG_ActiveProcessNotify,		0),
74271ab489SXiaojian Du 	MSG_MAP(SetHardMinIspiclkByFreq,        PPSMC_MSG_SetHardMinIspiclkByFreq,	0),
75271ab489SXiaojian Du 	MSG_MAP(SetHardMinIspxclkByFreq,        PPSMC_MSG_SetHardMinIspxclkByFreq,	0),
76271ab489SXiaojian Du 	MSG_MAP(SetDriverDramAddrHigh,          PPSMC_MSG_SetDriverDramAddrHigh,	0),
77271ab489SXiaojian Du 	MSG_MAP(SetDriverDramAddrLow,           PPSMC_MSG_SetDriverDramAddrLow,		0),
78271ab489SXiaojian Du 	MSG_MAP(TransferTableSmu2Dram,          PPSMC_MSG_TransferTableSmu2Dram,	0),
79271ab489SXiaojian Du 	MSG_MAP(TransferTableDram2Smu,          PPSMC_MSG_TransferTableDram2Smu,	0),
80271ab489SXiaojian Du 	MSG_MAP(GfxDeviceDriverReset,           PPSMC_MSG_GfxDeviceDriverReset,		0),
81271ab489SXiaojian Du 	MSG_MAP(GetEnabledSmuFeatures,          PPSMC_MSG_GetEnabledSmuFeatures,	0),
82271ab489SXiaojian Du 	MSG_MAP(Spare1,                         PPSMC_MSG_spare1,					0),
83271ab489SXiaojian Du 	MSG_MAP(SetHardMinSocclkByFreq,         PPSMC_MSG_SetHardMinSocclkByFreq,	0),
84271ab489SXiaojian Du 	MSG_MAP(SetSoftMinFclk,                 PPSMC_MSG_SetSoftMinFclk,		0),
85271ab489SXiaojian Du 	MSG_MAP(SetSoftMinVcn,                  PPSMC_MSG_SetSoftMinVcn,		0),
86271ab489SXiaojian Du 	MSG_MAP(EnablePostCode,                 PPSMC_MSG_EnablePostCode,		0),
87271ab489SXiaojian Du 	MSG_MAP(GetGfxclkFrequency,             PPSMC_MSG_GetGfxclkFrequency,	0),
88271ab489SXiaojian Du 	MSG_MAP(GetFclkFrequency,               PPSMC_MSG_GetFclkFrequency,		0),
89271ab489SXiaojian Du 	MSG_MAP(SetSoftMaxGfxClk,               PPSMC_MSG_SetSoftMaxGfxClk,		0),
90271ab489SXiaojian Du 	MSG_MAP(SetHardMinGfxClk,               PPSMC_MSG_SetHardMinGfxClk,		0),
91271ab489SXiaojian Du 	MSG_MAP(SetSoftMaxSocclkByFreq,         PPSMC_MSG_SetSoftMaxSocclkByFreq,	0),
92271ab489SXiaojian Du 	MSG_MAP(SetSoftMaxFclkByFreq,           PPSMC_MSG_SetSoftMaxFclkByFreq,		0),
93271ab489SXiaojian Du 	MSG_MAP(SetSoftMaxVcn,                  PPSMC_MSG_SetSoftMaxVcn,			0),
94271ab489SXiaojian Du 	MSG_MAP(Spare2,                         PPSMC_MSG_spare2,					0),
95271ab489SXiaojian Du 	MSG_MAP(SetPowerLimitPercentage,        PPSMC_MSG_SetPowerLimitPercentage,	0),
96271ab489SXiaojian Du 	MSG_MAP(PowerDownJpeg,                  PPSMC_MSG_PowerDownJpeg,			0),
97271ab489SXiaojian Du 	MSG_MAP(PowerUpJpeg,                    PPSMC_MSG_PowerUpJpeg,				0),
98271ab489SXiaojian Du 	MSG_MAP(SetHardMinFclkByFreq,           PPSMC_MSG_SetHardMinFclkByFreq,		0),
99271ab489SXiaojian Du 	MSG_MAP(SetSoftMinSocclkByFreq,         PPSMC_MSG_SetSoftMinSocclkByFreq,	0),
100271ab489SXiaojian Du 	MSG_MAP(PowerUpCvip,                    PPSMC_MSG_PowerUpCvip,				0),
101271ab489SXiaojian Du 	MSG_MAP(PowerDownCvip,                  PPSMC_MSG_PowerDownCvip,			0),
102271ab489SXiaojian Du 	MSG_MAP(GetPptLimit,                        PPSMC_MSG_GetPptLimit,			0),
103271ab489SXiaojian Du 	MSG_MAP(GetThermalLimit,                    PPSMC_MSG_GetThermalLimit,		0),
104271ab489SXiaojian Du 	MSG_MAP(GetCurrentTemperature,              PPSMC_MSG_GetCurrentTemperature, 0),
105271ab489SXiaojian Du 	MSG_MAP(GetCurrentPower,                    PPSMC_MSG_GetCurrentPower,		 0),
106271ab489SXiaojian Du 	MSG_MAP(GetCurrentVoltage,                  PPSMC_MSG_GetCurrentVoltage,	 0),
107271ab489SXiaojian Du 	MSG_MAP(GetCurrentCurrent,                  PPSMC_MSG_GetCurrentCurrent,	 0),
108271ab489SXiaojian Du 	MSG_MAP(GetAverageCpuActivity,              PPSMC_MSG_GetAverageCpuActivity, 0),
109271ab489SXiaojian Du 	MSG_MAP(GetAverageGfxActivity,              PPSMC_MSG_GetAverageGfxActivity, 0),
110271ab489SXiaojian Du 	MSG_MAP(GetAveragePower,                    PPSMC_MSG_GetAveragePower,		 0),
111271ab489SXiaojian Du 	MSG_MAP(GetAverageTemperature,              PPSMC_MSG_GetAverageTemperature, 0),
112271ab489SXiaojian Du 	MSG_MAP(SetAveragePowerTimeConstant,        PPSMC_MSG_SetAveragePowerTimeConstant,			0),
113271ab489SXiaojian Du 	MSG_MAP(SetAverageActivityTimeConstant,     PPSMC_MSG_SetAverageActivityTimeConstant,		0),
114271ab489SXiaojian Du 	MSG_MAP(SetAverageTemperatureTimeConstant,  PPSMC_MSG_SetAverageTemperatureTimeConstant,	0),
115271ab489SXiaojian Du 	MSG_MAP(SetMitigationEndHysteresis,         PPSMC_MSG_SetMitigationEndHysteresis,			0),
116271ab489SXiaojian Du 	MSG_MAP(GetCurrentFreq,                     PPSMC_MSG_GetCurrentFreq,						0),
117271ab489SXiaojian Du 	MSG_MAP(SetReducedPptLimit,                 PPSMC_MSG_SetReducedPptLimit,					0),
118271ab489SXiaojian Du 	MSG_MAP(SetReducedThermalLimit,             PPSMC_MSG_SetReducedThermalLimit,				0),
119271ab489SXiaojian Du 	MSG_MAP(DramLogSetDramAddr,                 PPSMC_MSG_DramLogSetDramAddr,					0),
120271ab489SXiaojian Du 	MSG_MAP(StartDramLogging,                   PPSMC_MSG_StartDramLogging,						0),
121271ab489SXiaojian Du 	MSG_MAP(StopDramLogging,                    PPSMC_MSG_StopDramLogging,						0),
122271ab489SXiaojian Du 	MSG_MAP(SetSoftMinCclk,                     PPSMC_MSG_SetSoftMinCclk,						0),
123271ab489SXiaojian Du 	MSG_MAP(SetSoftMaxCclk,                     PPSMC_MSG_SetSoftMaxCclk,						0),
124eefdf047SJinzhou Su 	MSG_MAP(RequestActiveWgp,                   PPSMC_MSG_RequestActiveWgp,                     0),
125f46a221bSXiaojian Du };
126f46a221bSXiaojian Du 
127f46a221bSXiaojian Du static struct cmn2asic_mapping vangogh_feature_mask_map[SMU_FEATURE_COUNT] = {
128f46a221bSXiaojian Du 	FEA_MAP(PPT),
129f46a221bSXiaojian Du 	FEA_MAP(TDC),
130f46a221bSXiaojian Du 	FEA_MAP(THERMAL),
131f46a221bSXiaojian Du 	FEA_MAP(DS_GFXCLK),
132f46a221bSXiaojian Du 	FEA_MAP(DS_SOCCLK),
133f46a221bSXiaojian Du 	FEA_MAP(DS_LCLK),
134f46a221bSXiaojian Du 	FEA_MAP(DS_FCLK),
135f46a221bSXiaojian Du 	FEA_MAP(DS_MP1CLK),
136f46a221bSXiaojian Du 	FEA_MAP(DS_MP0CLK),
137f46a221bSXiaojian Du 	FEA_MAP(ATHUB_PG),
138f46a221bSXiaojian Du 	FEA_MAP(CCLK_DPM),
139f46a221bSXiaojian Du 	FEA_MAP(FAN_CONTROLLER),
140f46a221bSXiaojian Du 	FEA_MAP(ULV),
141f46a221bSXiaojian Du 	FEA_MAP(VCN_DPM),
142f46a221bSXiaojian Du 	FEA_MAP(LCLK_DPM),
143f46a221bSXiaojian Du 	FEA_MAP(SHUBCLK_DPM),
144f46a221bSXiaojian Du 	FEA_MAP(DCFCLK_DPM),
145f46a221bSXiaojian Du 	FEA_MAP(DS_DCFCLK),
146f46a221bSXiaojian Du 	FEA_MAP(S0I2),
147f46a221bSXiaojian Du 	FEA_MAP(SMU_LOW_POWER),
148f46a221bSXiaojian Du 	FEA_MAP(GFX_DEM),
149f46a221bSXiaojian Du 	FEA_MAP(PSI),
150f46a221bSXiaojian Du 	FEA_MAP(PROCHOT),
151f46a221bSXiaojian Du 	FEA_MAP(CPUOFF),
152f46a221bSXiaojian Du 	FEA_MAP(STAPM),
153f46a221bSXiaojian Du 	FEA_MAP(S0I3),
154f46a221bSXiaojian Du 	FEA_MAP(DF_CSTATES),
155f46a221bSXiaojian Du 	FEA_MAP(PERF_LIMIT),
156f46a221bSXiaojian Du 	FEA_MAP(CORE_DLDO),
157f46a221bSXiaojian Du 	FEA_MAP(RSMU_LOW_POWER),
158f46a221bSXiaojian Du 	FEA_MAP(SMN_LOW_POWER),
159f46a221bSXiaojian Du 	FEA_MAP(THM_LOW_POWER),
160f46a221bSXiaojian Du 	FEA_MAP(SMUIO_LOW_POWER),
161f46a221bSXiaojian Du 	FEA_MAP(MP1_LOW_POWER),
162f46a221bSXiaojian Du 	FEA_MAP(DS_VCN),
163f46a221bSXiaojian Du 	FEA_MAP(CPPC),
164f46a221bSXiaojian Du 	FEA_MAP(OS_CSTATES),
165f46a221bSXiaojian Du 	FEA_MAP(ISP_DPM),
166f46a221bSXiaojian Du 	FEA_MAP(A55_DPM),
167f46a221bSXiaojian Du 	FEA_MAP(CVIP_DSP_DPM),
168f46a221bSXiaojian Du 	FEA_MAP(MSMU_LOW_POWER),
16954800b58SXiaojian Du 	FEA_MAP_REVERSE(SOCCLK),
17054800b58SXiaojian Du 	FEA_MAP_REVERSE(FCLK),
17154800b58SXiaojian Du 	FEA_MAP_HALF_REVERSE(GFX),
172f46a221bSXiaojian Du };
173f46a221bSXiaojian Du 
174f46a221bSXiaojian Du static struct cmn2asic_mapping vangogh_table_map[SMU_TABLE_COUNT] = {
175f46a221bSXiaojian Du 	TAB_MAP_VALID(WATERMARKS),
176f46a221bSXiaojian Du 	TAB_MAP_VALID(SMU_METRICS),
177f46a221bSXiaojian Du 	TAB_MAP_VALID(CUSTOM_DPM),
178f46a221bSXiaojian Du 	TAB_MAP_VALID(DPMCLOCKS),
179f46a221bSXiaojian Du };
180f46a221bSXiaojian Du 
181f46a221bSXiaojian Du static int vangogh_tables_init(struct smu_context *smu)
182f46a221bSXiaojian Du {
183f46a221bSXiaojian Du 	struct smu_table_context *smu_table = &smu->smu_table;
184f46a221bSXiaojian Du 	struct smu_table *tables = smu_table->tables;
185f46a221bSXiaojian Du 
186f46a221bSXiaojian Du 	SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
187f46a221bSXiaojian Du 		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
188f46a221bSXiaojian Du 	SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
189f46a221bSXiaojian Du 		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
190f46a221bSXiaojian Du 	SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),
191f46a221bSXiaojian Du 		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
192f46a221bSXiaojian Du 	SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE,
193f46a221bSXiaojian Du 		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
194f46a221bSXiaojian Du 	SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF, sizeof(DpmActivityMonitorCoeffExt_t),
195f46a221bSXiaojian Du 		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
196f46a221bSXiaojian Du 	smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
197f46a221bSXiaojian Du 	if (!smu_table->metrics_table)
198f46a221bSXiaojian Du 		goto err0_out;
199f46a221bSXiaojian Du 	smu_table->metrics_time = 0;
200f46a221bSXiaojian Du 
201f46a221bSXiaojian Du 	smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_0);
202f46a221bSXiaojian Du 	smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
203f46a221bSXiaojian Du 	if (!smu_table->gpu_metrics_table)
204f46a221bSXiaojian Du 		goto err1_out;
205f46a221bSXiaojian Du 
206f46a221bSXiaojian Du 	smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
207f46a221bSXiaojian Du 	if (!smu_table->watermarks_table)
208f46a221bSXiaojian Du 		goto err2_out;
209f46a221bSXiaojian Du 
210c98ee897SXiaojian Du 	smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL);
211c98ee897SXiaojian Du 	if (!smu_table->clocks_table)
212c98ee897SXiaojian Du 		goto err3_out;
213c98ee897SXiaojian Du 
214f46a221bSXiaojian Du 	return 0;
215f46a221bSXiaojian Du 
216c98ee897SXiaojian Du err3_out:
217c98ee897SXiaojian Du 	kfree(smu_table->clocks_table);
218f46a221bSXiaojian Du err2_out:
219f46a221bSXiaojian Du 	kfree(smu_table->gpu_metrics_table);
220f46a221bSXiaojian Du err1_out:
221f46a221bSXiaojian Du 	kfree(smu_table->metrics_table);
222f46a221bSXiaojian Du err0_out:
223f46a221bSXiaojian Du 	return -ENOMEM;
224f46a221bSXiaojian Du }
225f46a221bSXiaojian Du 
226271ab489SXiaojian Du static int vangogh_get_smu_metrics_data(struct smu_context *smu,
227271ab489SXiaojian Du 				       MetricsMember_t member,
228271ab489SXiaojian Du 				       uint32_t *value)
229271ab489SXiaojian Du {
230271ab489SXiaojian Du 	struct smu_table_context *smu_table = &smu->smu_table;
231271ab489SXiaojian Du 
232271ab489SXiaojian Du 	SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
233271ab489SXiaojian Du 	int ret = 0;
234271ab489SXiaojian Du 
235271ab489SXiaojian Du 	mutex_lock(&smu->metrics_lock);
236271ab489SXiaojian Du 
237271ab489SXiaojian Du 	ret = smu_cmn_get_metrics_table_locked(smu,
238271ab489SXiaojian Du 					       NULL,
239271ab489SXiaojian Du 					       false);
240271ab489SXiaojian Du 	if (ret) {
241271ab489SXiaojian Du 		mutex_unlock(&smu->metrics_lock);
242271ab489SXiaojian Du 		return ret;
243271ab489SXiaojian Du 	}
244271ab489SXiaojian Du 
245271ab489SXiaojian Du 	switch (member) {
246271ab489SXiaojian Du 	case METRICS_AVERAGE_GFXCLK:
247271ab489SXiaojian Du 		*value = metrics->GfxclkFrequency;
248271ab489SXiaojian Du 		break;
249271ab489SXiaojian Du 	case METRICS_AVERAGE_SOCCLK:
250271ab489SXiaojian Du 		*value = metrics->SocclkFrequency;
251271ab489SXiaojian Du 		break;
252f02c7336SXiaojian Du 	case METRICS_AVERAGE_VCLK:
253f02c7336SXiaojian Du 		*value = metrics->VclkFrequency;
254f02c7336SXiaojian Du 		break;
255f02c7336SXiaojian Du 	case METRICS_AVERAGE_DCLK:
256f02c7336SXiaojian Du 		*value = metrics->DclkFrequency;
257f02c7336SXiaojian Du 		break;
258271ab489SXiaojian Du 	case METRICS_AVERAGE_UCLK:
259271ab489SXiaojian Du 		*value = metrics->MemclkFrequency;
260271ab489SXiaojian Du 		break;
261271ab489SXiaojian Du 	case METRICS_AVERAGE_GFXACTIVITY:
262271ab489SXiaojian Du 		*value = metrics->GfxActivity / 100;
263271ab489SXiaojian Du 		break;
264271ab489SXiaojian Du 	case METRICS_AVERAGE_VCNACTIVITY:
265271ab489SXiaojian Du 		*value = metrics->UvdActivity;
266271ab489SXiaojian Du 		break;
267271ab489SXiaojian Du 	case METRICS_AVERAGE_SOCKETPOWER:
26823289a22SXiaojian Du 		*value = (metrics->CurrentSocketPower << 8) /
26923289a22SXiaojian Du 		1000 ;
270271ab489SXiaojian Du 		break;
271271ab489SXiaojian Du 	case METRICS_TEMPERATURE_EDGE:
272271ab489SXiaojian Du 		*value = metrics->GfxTemperature / 100 *
273271ab489SXiaojian Du 		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
274271ab489SXiaojian Du 		break;
275271ab489SXiaojian Du 	case METRICS_TEMPERATURE_HOTSPOT:
276271ab489SXiaojian Du 		*value = metrics->SocTemperature / 100 *
277271ab489SXiaojian Du 		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
278271ab489SXiaojian Du 		break;
279271ab489SXiaojian Du 	case METRICS_THROTTLER_STATUS:
280271ab489SXiaojian Du 		*value = metrics->ThrottlerStatus;
281271ab489SXiaojian Du 		break;
2822139d12bSAlex Deucher 	case METRICS_VOLTAGE_VDDGFX:
2832139d12bSAlex Deucher 		*value = metrics->Voltage[2];
2842139d12bSAlex Deucher 		break;
2852139d12bSAlex Deucher 	case METRICS_VOLTAGE_VDDSOC:
2862139d12bSAlex Deucher 		*value = metrics->Voltage[1];
2872139d12bSAlex Deucher 		break;
288271ab489SXiaojian Du 	default:
289271ab489SXiaojian Du 		*value = UINT_MAX;
290271ab489SXiaojian Du 		break;
291271ab489SXiaojian Du 	}
292271ab489SXiaojian Du 
293271ab489SXiaojian Du 	mutex_unlock(&smu->metrics_lock);
294271ab489SXiaojian Du 
295271ab489SXiaojian Du 	return ret;
296271ab489SXiaojian Du }
297271ab489SXiaojian Du 
298f46a221bSXiaojian Du static int vangogh_allocate_dpm_context(struct smu_context *smu)
299f46a221bSXiaojian Du {
300f46a221bSXiaojian Du 	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
301f46a221bSXiaojian Du 
302f46a221bSXiaojian Du 	smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context),
303f46a221bSXiaojian Du 				       GFP_KERNEL);
304f46a221bSXiaojian Du 	if (!smu_dpm->dpm_context)
305f46a221bSXiaojian Du 		return -ENOMEM;
306f46a221bSXiaojian Du 
307f46a221bSXiaojian Du 	smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context);
308f46a221bSXiaojian Du 
309f46a221bSXiaojian Du 	return 0;
310f46a221bSXiaojian Du }
311f46a221bSXiaojian Du 
312f46a221bSXiaojian Du static int vangogh_init_smc_tables(struct smu_context *smu)
313f46a221bSXiaojian Du {
314f46a221bSXiaojian Du 	int ret = 0;
315f46a221bSXiaojian Du 
316f46a221bSXiaojian Du 	ret = vangogh_tables_init(smu);
317f46a221bSXiaojian Du 	if (ret)
318f46a221bSXiaojian Du 		return ret;
319f46a221bSXiaojian Du 
320f46a221bSXiaojian Du 	ret = vangogh_allocate_dpm_context(smu);
321f46a221bSXiaojian Du 	if (ret)
322f46a221bSXiaojian Du 		return ret;
323f46a221bSXiaojian Du 
324f46a221bSXiaojian Du 	return smu_v11_0_init_smc_tables(smu);
325f46a221bSXiaojian Du }
326f46a221bSXiaojian Du 
327f46a221bSXiaojian Du static int vangogh_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
328f46a221bSXiaojian Du {
329f46a221bSXiaojian Du 	int ret = 0;
330f46a221bSXiaojian Du 
331f46a221bSXiaojian Du 	if (enable) {
332f46a221bSXiaojian Du 		/* vcn dpm on is a prerequisite for vcn power gate messages */
333f46a221bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL);
334f46a221bSXiaojian Du 		if (ret)
335f46a221bSXiaojian Du 			return ret;
336f46a221bSXiaojian Du 	} else {
337f46a221bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL);
338f46a221bSXiaojian Du 		if (ret)
339f46a221bSXiaojian Du 			return ret;
340f46a221bSXiaojian Du 	}
341f46a221bSXiaojian Du 
342f46a221bSXiaojian Du 	return ret;
343f46a221bSXiaojian Du }
344f46a221bSXiaojian Du 
345f46a221bSXiaojian Du static int vangogh_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
346f46a221bSXiaojian Du {
347f46a221bSXiaojian Du 	int ret = 0;
348f46a221bSXiaojian Du 
349f46a221bSXiaojian Du 	if (enable) {
350f46a221bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpJpeg, 0, NULL);
351f46a221bSXiaojian Du 		if (ret)
352f46a221bSXiaojian Du 			return ret;
353f46a221bSXiaojian Du 	} else {
354f46a221bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL);
355f46a221bSXiaojian Du 		if (ret)
356f46a221bSXiaojian Du 			return ret;
357f46a221bSXiaojian Du 	}
358f46a221bSXiaojian Du 
359f46a221bSXiaojian Du 	return ret;
360f46a221bSXiaojian Du }
361f46a221bSXiaojian Du 
362f46a221bSXiaojian Du static bool vangogh_is_dpm_running(struct smu_context *smu)
363f46a221bSXiaojian Du {
364271ab489SXiaojian Du 	int ret = 0;
365271ab489SXiaojian Du 	uint32_t feature_mask[2];
366271ab489SXiaojian Du 	uint64_t feature_enabled;
367f46a221bSXiaojian Du 
368271ab489SXiaojian Du 	ret = smu_cmn_get_enabled_32_bits_mask(smu, feature_mask, 2);
369271ab489SXiaojian Du 
370271ab489SXiaojian Du 	if (ret)
371f46a221bSXiaojian Du 		return false;
372f46a221bSXiaojian Du 
373271ab489SXiaojian Du 	feature_enabled = (unsigned long)((uint64_t)feature_mask[0] |
374271ab489SXiaojian Du 				((uint64_t)feature_mask[1] << 32));
375271ab489SXiaojian Du 
376271ab489SXiaojian Du 	return !!(feature_enabled & SMC_DPM_FEATURE);
377271ab489SXiaojian Du }
378271ab489SXiaojian Du 
379ae7b32e7SXiaojian Du static int vangogh_get_dpm_clk_limited(struct smu_context *smu, enum smu_clk_type clk_type,
380ae7b32e7SXiaojian Du 						uint32_t dpm_level, uint32_t *freq)
381ae7b32e7SXiaojian Du {
382ae7b32e7SXiaojian Du 	DpmClocks_t *clk_table = smu->smu_table.clocks_table;
383ae7b32e7SXiaojian Du 
384ae7b32e7SXiaojian Du 	if (!clk_table || clk_type >= SMU_CLK_COUNT)
385ae7b32e7SXiaojian Du 		return -EINVAL;
386ae7b32e7SXiaojian Du 
387ae7b32e7SXiaojian Du 	switch (clk_type) {
388ae7b32e7SXiaojian Du 	case SMU_SOCCLK:
389ae7b32e7SXiaojian Du 		if (dpm_level >= clk_table->NumSocClkLevelsEnabled)
390ae7b32e7SXiaojian Du 			return -EINVAL;
391ae7b32e7SXiaojian Du 		*freq = clk_table->SocClocks[dpm_level];
392ae7b32e7SXiaojian Du 		break;
393f02c7336SXiaojian Du 	case SMU_VCLK:
394f02c7336SXiaojian Du 		if (dpm_level >= clk_table->VcnClkLevelsEnabled)
395f02c7336SXiaojian Du 			return -EINVAL;
396f02c7336SXiaojian Du 		*freq = clk_table->VcnClocks[dpm_level].vclk;
397f02c7336SXiaojian Du 		break;
398f02c7336SXiaojian Du 	case SMU_DCLK:
399f02c7336SXiaojian Du 		if (dpm_level >= clk_table->VcnClkLevelsEnabled)
400f02c7336SXiaojian Du 			return -EINVAL;
401f02c7336SXiaojian Du 		*freq = clk_table->VcnClocks[dpm_level].dclk;
402f02c7336SXiaojian Du 		break;
403ae7b32e7SXiaojian Du 	case SMU_UCLK:
404ae7b32e7SXiaojian Du 	case SMU_MCLK:
405ae7b32e7SXiaojian Du 		if (dpm_level >= clk_table->NumDfPstatesEnabled)
406ae7b32e7SXiaojian Du 			return -EINVAL;
407ae7b32e7SXiaojian Du 		*freq = clk_table->DfPstateTable[dpm_level].memclk;
408ae7b32e7SXiaojian Du 
409ae7b32e7SXiaojian Du 		break;
410ae7b32e7SXiaojian Du 	case SMU_FCLK:
411ae7b32e7SXiaojian Du 		if (dpm_level >= clk_table->NumDfPstatesEnabled)
412ae7b32e7SXiaojian Du 			return -EINVAL;
413ae7b32e7SXiaojian Du 		*freq = clk_table->DfPstateTable[dpm_level].fclk;
414ae7b32e7SXiaojian Du 		break;
415ae7b32e7SXiaojian Du 	default:
416ae7b32e7SXiaojian Du 		return -EINVAL;
417ae7b32e7SXiaojian Du 	}
418ae7b32e7SXiaojian Du 
419ae7b32e7SXiaojian Du 	return 0;
420ae7b32e7SXiaojian Du }
421ae7b32e7SXiaojian Du 
422c98ee897SXiaojian Du static int vangogh_print_fine_grain_clk(struct smu_context *smu,
423c98ee897SXiaojian Du 			enum smu_clk_type clk_type, char *buf)
424c98ee897SXiaojian Du {
425ae7b32e7SXiaojian Du 	DpmClocks_t *clk_table = smu->smu_table.clocks_table;
426ae7b32e7SXiaojian Du 	SmuMetrics_t metrics;
427ae7b32e7SXiaojian Du 	int i, size = 0, ret = 0;
428ae7b32e7SXiaojian Du 	uint32_t cur_value = 0, value = 0, count = 0;
429ae7b32e7SXiaojian Du 	bool cur_value_match_level = false;
430ae7b32e7SXiaojian Du 
431ae7b32e7SXiaojian Du 	memset(&metrics, 0, sizeof(metrics));
432ae7b32e7SXiaojian Du 
433ae7b32e7SXiaojian Du 	ret = smu_cmn_get_metrics_table(smu, &metrics, false);
434ae7b32e7SXiaojian Du 	if (ret)
435ae7b32e7SXiaojian Du 		return ret;
436c98ee897SXiaojian Du 
437c98ee897SXiaojian Du 	switch (clk_type) {
438c98ee897SXiaojian Du 	case SMU_OD_SCLK:
439c98ee897SXiaojian Du 		if (smu->od_enabled) {
440c98ee897SXiaojian Du 			size = sprintf(buf, "%s:\n", "OD_SCLK");
441c98ee897SXiaojian Du 			size += sprintf(buf + size, "0: %10uMhz\n",
442c98ee897SXiaojian Du 			(smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq);
443c98ee897SXiaojian Du 			size += sprintf(buf + size, "1: %10uMhz\n",
444c98ee897SXiaojian Du 			(smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq);
445c98ee897SXiaojian Du 		}
446c98ee897SXiaojian Du 		break;
447c98ee897SXiaojian Du 	case SMU_OD_RANGE:
448c98ee897SXiaojian Du 		if (smu->od_enabled) {
449c98ee897SXiaojian Du 			size = sprintf(buf, "%s:\n", "OD_RANGE");
450c98ee897SXiaojian Du 			size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n",
451c98ee897SXiaojian Du 				smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq);
452c98ee897SXiaojian Du 		}
453c98ee897SXiaojian Du 		break;
454ae7b32e7SXiaojian Du 	case SMU_SOCCLK:
455ae7b32e7SXiaojian Du 		/* the level 3 ~ 6 of socclk use the same frequency for vangogh */
456ae7b32e7SXiaojian Du 		count = clk_table->NumSocClkLevelsEnabled;
457ae7b32e7SXiaojian Du 		cur_value = metrics.SocclkFrequency;
458ae7b32e7SXiaojian Du 		break;
459f02c7336SXiaojian Du 	case SMU_VCLK:
460f02c7336SXiaojian Du 		count = clk_table->VcnClkLevelsEnabled;
461f02c7336SXiaojian Du 		cur_value = metrics.VclkFrequency;
462f02c7336SXiaojian Du 		break;
463f02c7336SXiaojian Du 	case SMU_DCLK:
464f02c7336SXiaojian Du 		count = clk_table->VcnClkLevelsEnabled;
465f02c7336SXiaojian Du 		cur_value = metrics.DclkFrequency;
466f02c7336SXiaojian Du 		break;
467ae7b32e7SXiaojian Du 	case SMU_MCLK:
468ae7b32e7SXiaojian Du 		count = clk_table->NumDfPstatesEnabled;
469ae7b32e7SXiaojian Du 		cur_value = metrics.MemclkFrequency;
470ae7b32e7SXiaojian Du 		break;
471ae7b32e7SXiaojian Du 	case SMU_FCLK:
472ae7b32e7SXiaojian Du 		count = clk_table->NumDfPstatesEnabled;
473ae7b32e7SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetFclkFrequency, 0, &cur_value);
474ae7b32e7SXiaojian Du 		if (ret)
475ae7b32e7SXiaojian Du 			return ret;
476ae7b32e7SXiaojian Du 		break;
477ae7b32e7SXiaojian Du 	default:
478ae7b32e7SXiaojian Du 		break;
479ae7b32e7SXiaojian Du 	}
480ae7b32e7SXiaojian Du 
481ae7b32e7SXiaojian Du 	switch (clk_type) {
482ae7b32e7SXiaojian Du 	case SMU_SOCCLK:
483f02c7336SXiaojian Du 	case SMU_VCLK:
484f02c7336SXiaojian Du 	case SMU_DCLK:
485ae7b32e7SXiaojian Du 	case SMU_MCLK:
486ae7b32e7SXiaojian Du 	case SMU_FCLK:
487ae7b32e7SXiaojian Du 		for (i = 0; i < count; i++) {
488ae7b32e7SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, i, &value);
489ae7b32e7SXiaojian Du 			if (ret)
490ae7b32e7SXiaojian Du 				return ret;
491ae7b32e7SXiaojian Du 			if (!value)
492ae7b32e7SXiaojian Du 				continue;
493ae7b32e7SXiaojian Du 			size += sprintf(buf + size, "%d: %uMhz %s\n", i, value,
494ae7b32e7SXiaojian Du 					cur_value == value ? "*" : "");
495ae7b32e7SXiaojian Du 			if (cur_value == value)
496ae7b32e7SXiaojian Du 				cur_value_match_level = true;
497ae7b32e7SXiaojian Du 		}
498ae7b32e7SXiaojian Du 
499ae7b32e7SXiaojian Du 		if (!cur_value_match_level)
500ae7b32e7SXiaojian Du 			size += sprintf(buf + size, "   %uMhz *\n", cur_value);
501ae7b32e7SXiaojian Du 		break;
502c98ee897SXiaojian Du 	default:
503c98ee897SXiaojian Du 		break;
504c98ee897SXiaojian Du 	}
505c98ee897SXiaojian Du 
506c98ee897SXiaojian Du 	return size;
507c98ee897SXiaojian Du }
508c98ee897SXiaojian Du 
509d0e4e112SXiaojian Du static int vangogh_get_profiling_clk_mask(struct smu_context *smu,
510d0e4e112SXiaojian Du 					 enum amd_dpm_forced_level level,
511d0e4e112SXiaojian Du 					 uint32_t *vclk_mask,
512d0e4e112SXiaojian Du 					 uint32_t *dclk_mask,
513d0e4e112SXiaojian Du 					 uint32_t *mclk_mask,
514d0e4e112SXiaojian Du 					 uint32_t *fclk_mask,
515d0e4e112SXiaojian Du 					 uint32_t *soc_mask)
516d0e4e112SXiaojian Du {
517d0e4e112SXiaojian Du 	DpmClocks_t *clk_table = smu->smu_table.clocks_table;
518d0e4e112SXiaojian Du 
519307f049bSXiaojian Du 	if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
520d0e4e112SXiaojian Du 		if (mclk_mask)
521d0e4e112SXiaojian Du 			*mclk_mask = clk_table->NumDfPstatesEnabled - 1;
522307f049bSXiaojian Du 
523d0e4e112SXiaojian Du 		if (fclk_mask)
524d0e4e112SXiaojian Du 			*fclk_mask = clk_table->NumDfPstatesEnabled - 1;
525307f049bSXiaojian Du 
526307f049bSXiaojian Du 		if (soc_mask)
527307f049bSXiaojian Du 			*soc_mask = 0;
528d0e4e112SXiaojian Du 	} else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
529d0e4e112SXiaojian Du 		if (mclk_mask)
530d0e4e112SXiaojian Du 			*mclk_mask = 0;
531307f049bSXiaojian Du 
532d0e4e112SXiaojian Du 		if (fclk_mask)
533d0e4e112SXiaojian Du 			*fclk_mask = 0;
534d0e4e112SXiaojian Du 
535d0e4e112SXiaojian Du 		if (soc_mask)
536307f049bSXiaojian Du 			*soc_mask = 1;
537307f049bSXiaojian Du 
538307f049bSXiaojian Du 		if (vclk_mask)
539307f049bSXiaojian Du 			*vclk_mask = 1;
540307f049bSXiaojian Du 
541307f049bSXiaojian Du 		if (dclk_mask)
542307f049bSXiaojian Du 			*dclk_mask = 1;
543307f049bSXiaojian Du 	} else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD) {
544307f049bSXiaojian Du 		if (mclk_mask)
545307f049bSXiaojian Du 			*mclk_mask = 0;
546307f049bSXiaojian Du 
547307f049bSXiaojian Du 		if (fclk_mask)
548307f049bSXiaojian Du 			*fclk_mask = 0;
549307f049bSXiaojian Du 
550307f049bSXiaojian Du 		if (soc_mask)
551307f049bSXiaojian Du 			*soc_mask = 1;
552307f049bSXiaojian Du 
553307f049bSXiaojian Du 		if (vclk_mask)
554307f049bSXiaojian Du 			*vclk_mask = 1;
555307f049bSXiaojian Du 
556307f049bSXiaojian Du 		if (dclk_mask)
557307f049bSXiaojian Du 			*dclk_mask = 1;
558d0e4e112SXiaojian Du 	}
559d0e4e112SXiaojian Du 
560d0e4e112SXiaojian Du 	return 0;
561d0e4e112SXiaojian Du }
562d0e4e112SXiaojian Du 
563d0e4e112SXiaojian Du bool vangogh_clk_dpm_is_enabled(struct smu_context *smu,
564d0e4e112SXiaojian Du 				enum smu_clk_type clk_type)
565d0e4e112SXiaojian Du {
566d0e4e112SXiaojian Du 	enum smu_feature_mask feature_id = 0;
567d0e4e112SXiaojian Du 
568d0e4e112SXiaojian Du 	switch (clk_type) {
569d0e4e112SXiaojian Du 	case SMU_MCLK:
570d0e4e112SXiaojian Du 	case SMU_UCLK:
571d0e4e112SXiaojian Du 	case SMU_FCLK:
572d0e4e112SXiaojian Du 		feature_id = SMU_FEATURE_DPM_FCLK_BIT;
573d0e4e112SXiaojian Du 		break;
574d0e4e112SXiaojian Du 	case SMU_GFXCLK:
575d0e4e112SXiaojian Du 	case SMU_SCLK:
576d0e4e112SXiaojian Du 		feature_id = SMU_FEATURE_DPM_GFXCLK_BIT;
577d0e4e112SXiaojian Du 		break;
578d0e4e112SXiaojian Du 	case SMU_SOCCLK:
579d0e4e112SXiaojian Du 		feature_id = SMU_FEATURE_DPM_SOCCLK_BIT;
580d0e4e112SXiaojian Du 		break;
581d0e4e112SXiaojian Du 	case SMU_VCLK:
582d0e4e112SXiaojian Du 	case SMU_DCLK:
583d0e4e112SXiaojian Du 		feature_id = SMU_FEATURE_VCN_DPM_BIT;
584d0e4e112SXiaojian Du 		break;
585d0e4e112SXiaojian Du 	default:
586d0e4e112SXiaojian Du 		return true;
587d0e4e112SXiaojian Du 	}
588d0e4e112SXiaojian Du 
589d0e4e112SXiaojian Du 	if (!smu_cmn_feature_is_enabled(smu, feature_id))
590d0e4e112SXiaojian Du 		return false;
591d0e4e112SXiaojian Du 
592d0e4e112SXiaojian Du 	return true;
593d0e4e112SXiaojian Du }
594d0e4e112SXiaojian Du 
595d0e4e112SXiaojian Du static int vangogh_get_dpm_ultimate_freq(struct smu_context *smu,
596d0e4e112SXiaojian Du 					enum smu_clk_type clk_type,
597d0e4e112SXiaojian Du 					uint32_t *min,
598d0e4e112SXiaojian Du 					uint32_t *max)
599d0e4e112SXiaojian Du {
600d0e4e112SXiaojian Du 	int ret = 0;
601d0e4e112SXiaojian Du 	uint32_t soc_mask;
602d0e4e112SXiaojian Du 	uint32_t vclk_mask;
603d0e4e112SXiaojian Du 	uint32_t dclk_mask;
604d0e4e112SXiaojian Du 	uint32_t mclk_mask;
605d0e4e112SXiaojian Du 	uint32_t fclk_mask;
606d0e4e112SXiaojian Du 	uint32_t clock_limit;
607d0e4e112SXiaojian Du 
608d0e4e112SXiaojian Du 	if (!vangogh_clk_dpm_is_enabled(smu, clk_type)) {
609d0e4e112SXiaojian Du 		switch (clk_type) {
610d0e4e112SXiaojian Du 		case SMU_MCLK:
611d0e4e112SXiaojian Du 		case SMU_UCLK:
612d0e4e112SXiaojian Du 			clock_limit = smu->smu_table.boot_values.uclk;
613d0e4e112SXiaojian Du 			break;
614d0e4e112SXiaojian Du 		case SMU_FCLK:
615d0e4e112SXiaojian Du 			clock_limit = smu->smu_table.boot_values.fclk;
616d0e4e112SXiaojian Du 			break;
617d0e4e112SXiaojian Du 		case SMU_GFXCLK:
618d0e4e112SXiaojian Du 		case SMU_SCLK:
619d0e4e112SXiaojian Du 			clock_limit = smu->smu_table.boot_values.gfxclk;
620d0e4e112SXiaojian Du 			break;
621d0e4e112SXiaojian Du 		case SMU_SOCCLK:
622d0e4e112SXiaojian Du 			clock_limit = smu->smu_table.boot_values.socclk;
623d0e4e112SXiaojian Du 			break;
624d0e4e112SXiaojian Du 		case SMU_VCLK:
625d0e4e112SXiaojian Du 			clock_limit = smu->smu_table.boot_values.vclk;
626d0e4e112SXiaojian Du 			break;
627d0e4e112SXiaojian Du 		case SMU_DCLK:
628d0e4e112SXiaojian Du 			clock_limit = smu->smu_table.boot_values.dclk;
629d0e4e112SXiaojian Du 			break;
630d0e4e112SXiaojian Du 		default:
631d0e4e112SXiaojian Du 			clock_limit = 0;
632d0e4e112SXiaojian Du 			break;
633d0e4e112SXiaojian Du 		}
634d0e4e112SXiaojian Du 
635d0e4e112SXiaojian Du 		/* clock in Mhz unit */
636d0e4e112SXiaojian Du 		if (min)
637d0e4e112SXiaojian Du 			*min = clock_limit / 100;
638d0e4e112SXiaojian Du 		if (max)
639d0e4e112SXiaojian Du 			*max = clock_limit / 100;
640d0e4e112SXiaojian Du 
641d0e4e112SXiaojian Du 		return 0;
642d0e4e112SXiaojian Du 	}
643d0e4e112SXiaojian Du 	if (max) {
644d0e4e112SXiaojian Du 		ret = vangogh_get_profiling_clk_mask(smu,
645d0e4e112SXiaojian Du 							AMD_DPM_FORCED_LEVEL_PROFILE_PEAK,
646d0e4e112SXiaojian Du 							&vclk_mask,
647d0e4e112SXiaojian Du 							&dclk_mask,
648d0e4e112SXiaojian Du 							&mclk_mask,
649d0e4e112SXiaojian Du 							&fclk_mask,
650d0e4e112SXiaojian Du 							&soc_mask);
651d0e4e112SXiaojian Du 		if (ret)
652d0e4e112SXiaojian Du 			goto failed;
653d0e4e112SXiaojian Du 
654d0e4e112SXiaojian Du 		switch (clk_type) {
655d0e4e112SXiaojian Du 		case SMU_UCLK:
656d0e4e112SXiaojian Du 		case SMU_MCLK:
657d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, mclk_mask, max);
658d0e4e112SXiaojian Du 			if (ret)
659d0e4e112SXiaojian Du 				goto failed;
660d0e4e112SXiaojian Du 			break;
661d0e4e112SXiaojian Du 		case SMU_SOCCLK:
662d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, soc_mask, max);
663d0e4e112SXiaojian Du 			if (ret)
664d0e4e112SXiaojian Du 				goto failed;
665d0e4e112SXiaojian Du 			break;
666d0e4e112SXiaojian Du 		case SMU_FCLK:
667d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, fclk_mask, max);
668d0e4e112SXiaojian Du 			if (ret)
669d0e4e112SXiaojian Du 				goto failed;
670d0e4e112SXiaojian Du 			break;
671d0e4e112SXiaojian Du 		case SMU_VCLK:
672d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, vclk_mask, max);
673d0e4e112SXiaojian Du 			if (ret)
674d0e4e112SXiaojian Du 				goto failed;
675d0e4e112SXiaojian Du 			break;
676d0e4e112SXiaojian Du 		case SMU_DCLK:
677d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, dclk_mask, max);
678d0e4e112SXiaojian Du 			if (ret)
679d0e4e112SXiaojian Du 				goto failed;
680d0e4e112SXiaojian Du 			break;
681d0e4e112SXiaojian Du 		default:
682d0e4e112SXiaojian Du 			ret = -EINVAL;
683d0e4e112SXiaojian Du 			goto failed;
684d0e4e112SXiaojian Du 		}
685d0e4e112SXiaojian Du 	}
686d0e4e112SXiaojian Du 	if (min) {
687d0e4e112SXiaojian Du 		switch (clk_type) {
688d0e4e112SXiaojian Du 		case SMU_UCLK:
689d0e4e112SXiaojian Du 		case SMU_MCLK:
690d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, mclk_mask, min);
691d0e4e112SXiaojian Du 			if (ret)
692d0e4e112SXiaojian Du 				goto failed;
693d0e4e112SXiaojian Du 			break;
694d0e4e112SXiaojian Du 		case SMU_SOCCLK:
695d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, soc_mask, min);
696d0e4e112SXiaojian Du 			if (ret)
697d0e4e112SXiaojian Du 				goto failed;
698d0e4e112SXiaojian Du 			break;
699d0e4e112SXiaojian Du 		case SMU_FCLK:
700d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, fclk_mask, min);
701d0e4e112SXiaojian Du 			if (ret)
702d0e4e112SXiaojian Du 				goto failed;
703d0e4e112SXiaojian Du 			break;
704d0e4e112SXiaojian Du 		case SMU_VCLK:
705d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, vclk_mask, min);
706d0e4e112SXiaojian Du 			if (ret)
707d0e4e112SXiaojian Du 				goto failed;
708d0e4e112SXiaojian Du 			break;
709d0e4e112SXiaojian Du 		case SMU_DCLK:
710d0e4e112SXiaojian Du 			ret = vangogh_get_dpm_clk_limited(smu, clk_type, dclk_mask, min);
711d0e4e112SXiaojian Du 			if (ret)
712d0e4e112SXiaojian Du 				goto failed;
713d0e4e112SXiaojian Du 			break;
714d0e4e112SXiaojian Du 		default:
715d0e4e112SXiaojian Du 			ret = -EINVAL;
716d0e4e112SXiaojian Du 			goto failed;
717d0e4e112SXiaojian Du 		}
718d0e4e112SXiaojian Du 	}
719d0e4e112SXiaojian Du failed:
720d0e4e112SXiaojian Du 	return ret;
721d0e4e112SXiaojian Du }
722d0e4e112SXiaojian Du 
723307f049bSXiaojian Du static int vangogh_get_power_profile_mode(struct smu_context *smu,
724307f049bSXiaojian Du 					   char *buf)
725307f049bSXiaojian Du {
726307f049bSXiaojian Du 	static const char *profile_name[] = {
7272a38ca99SColin Ian King 					"BOOTUP_DEFAULT",
728307f049bSXiaojian Du 					"FULL_SCREEN_3D",
729307f049bSXiaojian Du 					"VIDEO",
730307f049bSXiaojian Du 					"VR",
731307f049bSXiaojian Du 					"COMPUTE",
732307f049bSXiaojian Du 					"CUSTOM"};
733307f049bSXiaojian Du 	uint32_t i, size = 0;
734307f049bSXiaojian Du 	int16_t workload_type = 0;
735307f049bSXiaojian Du 
736307f049bSXiaojian Du 	if (!buf)
737307f049bSXiaojian Du 		return -EINVAL;
738307f049bSXiaojian Du 
739307f049bSXiaojian Du 	for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
740307f049bSXiaojian Du 		/*
741307f049bSXiaojian Du 		 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
742307f049bSXiaojian Du 		 * Not all profile modes are supported on vangogh.
743307f049bSXiaojian Du 		 */
744307f049bSXiaojian Du 		workload_type = smu_cmn_to_asic_specific_index(smu,
745307f049bSXiaojian Du 							       CMN2ASIC_MAPPING_WORKLOAD,
746307f049bSXiaojian Du 							       i);
747307f049bSXiaojian Du 
748307f049bSXiaojian Du 		if (workload_type < 0)
749307f049bSXiaojian Du 			continue;
750307f049bSXiaojian Du 
751307f049bSXiaojian Du 		size += sprintf(buf + size, "%2d %14s%s\n",
752307f049bSXiaojian Du 			i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
753307f049bSXiaojian Du 	}
754307f049bSXiaojian Du 
755307f049bSXiaojian Du 	return size;
756307f049bSXiaojian Du }
757307f049bSXiaojian Du 
758d0e4e112SXiaojian Du static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
759d0e4e112SXiaojian Du {
760d0e4e112SXiaojian Du 	int workload_type, ret;
761d0e4e112SXiaojian Du 	uint32_t profile_mode = input[size];
762d0e4e112SXiaojian Du 
763d0e4e112SXiaojian Du 	if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
764d0e4e112SXiaojian Du 		dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);
765d0e4e112SXiaojian Du 		return -EINVAL;
766d0e4e112SXiaojian Du 	}
767d0e4e112SXiaojian Du 
768d0e4e112SXiaojian Du 	/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
769d0e4e112SXiaojian Du 	workload_type = smu_cmn_to_asic_specific_index(smu,
770d0e4e112SXiaojian Du 						       CMN2ASIC_MAPPING_WORKLOAD,
771d0e4e112SXiaojian Du 						       profile_mode);
772d0e4e112SXiaojian Du 	if (workload_type < 0) {
773d0e4e112SXiaojian Du 		dev_err_once(smu->adev->dev, "Unsupported power profile mode %d on VANGOGH\n",
774d0e4e112SXiaojian Du 					profile_mode);
775d0e4e112SXiaojian Du 		return -EINVAL;
776d0e4e112SXiaojian Du 	}
777d0e4e112SXiaojian Du 
778d0e4e112SXiaojian Du 	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
779d0e4e112SXiaojian Du 				    1 << workload_type,
780d0e4e112SXiaojian Du 				    NULL);
781d0e4e112SXiaojian Du 	if (ret) {
782d0e4e112SXiaojian Du 		dev_err_once(smu->adev->dev, "Fail to set workload type %d\n",
783d0e4e112SXiaojian Du 					workload_type);
784d0e4e112SXiaojian Du 		return ret;
785d0e4e112SXiaojian Du 	}
786d0e4e112SXiaojian Du 
787d0e4e112SXiaojian Du 	smu->power_profile_mode = profile_mode;
788d0e4e112SXiaojian Du 
789d0e4e112SXiaojian Du 	return 0;
790d0e4e112SXiaojian Du }
791d0e4e112SXiaojian Du 
792dd9e0b21SXiaojian Du static int vangogh_set_soft_freq_limited_range(struct smu_context *smu,
793dd9e0b21SXiaojian Du 					  enum smu_clk_type clk_type,
794dd9e0b21SXiaojian Du 					  uint32_t min,
795dd9e0b21SXiaojian Du 					  uint32_t max)
796dd9e0b21SXiaojian Du {
797dd9e0b21SXiaojian Du 	int ret = 0;
798dd9e0b21SXiaojian Du 
799dd9e0b21SXiaojian Du 	if (!vangogh_clk_dpm_is_enabled(smu, clk_type))
800dd9e0b21SXiaojian Du 		return 0;
801dd9e0b21SXiaojian Du 
802dd9e0b21SXiaojian Du 	switch (clk_type) {
803dd9e0b21SXiaojian Du 	case SMU_GFXCLK:
804dd9e0b21SXiaojian Du 	case SMU_SCLK:
805dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
806dd9e0b21SXiaojian Du 							SMU_MSG_SetHardMinGfxClk,
807dd9e0b21SXiaojian Du 							min, NULL);
808dd9e0b21SXiaojian Du 		if (ret)
809dd9e0b21SXiaojian Du 			return ret;
810dd9e0b21SXiaojian Du 
811dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
812dd9e0b21SXiaojian Du 							SMU_MSG_SetSoftMaxGfxClk,
813dd9e0b21SXiaojian Du 							max, NULL);
814dd9e0b21SXiaojian Du 		if (ret)
815dd9e0b21SXiaojian Du 			return ret;
816dd9e0b21SXiaojian Du 		break;
817dd9e0b21SXiaojian Du 	case SMU_FCLK:
818dd9e0b21SXiaojian Du 	case SMU_MCLK:
819dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
820dd9e0b21SXiaojian Du 							SMU_MSG_SetHardMinFclkByFreq,
821dd9e0b21SXiaojian Du 							min, NULL);
822dd9e0b21SXiaojian Du 		if (ret)
823dd9e0b21SXiaojian Du 			return ret;
824dd9e0b21SXiaojian Du 
825dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
826dd9e0b21SXiaojian Du 							SMU_MSG_SetSoftMaxFclkByFreq,
827dd9e0b21SXiaojian Du 							max, NULL);
828dd9e0b21SXiaojian Du 		if (ret)
829dd9e0b21SXiaojian Du 			return ret;
830dd9e0b21SXiaojian Du 		break;
831dd9e0b21SXiaojian Du 	case SMU_SOCCLK:
832dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
833dd9e0b21SXiaojian Du 							SMU_MSG_SetHardMinSocclkByFreq,
834dd9e0b21SXiaojian Du 							min, NULL);
835dd9e0b21SXiaojian Du 		if (ret)
836dd9e0b21SXiaojian Du 			return ret;
837dd9e0b21SXiaojian Du 
838dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
839dd9e0b21SXiaojian Du 							SMU_MSG_SetSoftMaxSocclkByFreq,
840dd9e0b21SXiaojian Du 							max, NULL);
841dd9e0b21SXiaojian Du 		if (ret)
842dd9e0b21SXiaojian Du 			return ret;
843dd9e0b21SXiaojian Du 		break;
844dd9e0b21SXiaojian Du 	case SMU_VCLK:
845dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
846dd9e0b21SXiaojian Du 							SMU_MSG_SetHardMinVcn,
847dd9e0b21SXiaojian Du 							min << 16, NULL);
848dd9e0b21SXiaojian Du 		if (ret)
849dd9e0b21SXiaojian Du 			return ret;
850dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
851dd9e0b21SXiaojian Du 							SMU_MSG_SetSoftMaxVcn,
852dd9e0b21SXiaojian Du 							max << 16, NULL);
853dd9e0b21SXiaojian Du 		if (ret)
854dd9e0b21SXiaojian Du 			return ret;
855dd9e0b21SXiaojian Du 		break;
856dd9e0b21SXiaojian Du 	case SMU_DCLK:
857dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
858dd9e0b21SXiaojian Du 							SMU_MSG_SetHardMinVcn,
859dd9e0b21SXiaojian Du 							min, NULL);
860dd9e0b21SXiaojian Du 		if (ret)
861dd9e0b21SXiaojian Du 			return ret;
862dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
863dd9e0b21SXiaojian Du 							SMU_MSG_SetSoftMaxVcn,
864dd9e0b21SXiaojian Du 							max, NULL);
865dd9e0b21SXiaojian Du 		if (ret)
866dd9e0b21SXiaojian Du 			return ret;
867dd9e0b21SXiaojian Du 		break;
868dd9e0b21SXiaojian Du 	default:
869dd9e0b21SXiaojian Du 		return -EINVAL;
870dd9e0b21SXiaojian Du 	}
871dd9e0b21SXiaojian Du 
872dd9e0b21SXiaojian Du 	return ret;
873dd9e0b21SXiaojian Du }
874dd9e0b21SXiaojian Du 
875dd9e0b21SXiaojian Du static int vangogh_force_clk_levels(struct smu_context *smu,
876dd9e0b21SXiaojian Du 				   enum smu_clk_type clk_type, uint32_t mask)
877dd9e0b21SXiaojian Du {
878dd9e0b21SXiaojian Du 	uint32_t soft_min_level = 0, soft_max_level = 0;
879dd9e0b21SXiaojian Du 	uint32_t min_freq = 0, max_freq = 0;
880dd9e0b21SXiaojian Du 	int ret = 0 ;
881dd9e0b21SXiaojian Du 
882dd9e0b21SXiaojian Du 	soft_min_level = mask ? (ffs(mask) - 1) : 0;
883dd9e0b21SXiaojian Du 	soft_max_level = mask ? (fls(mask) - 1) : 0;
884dd9e0b21SXiaojian Du 
885dd9e0b21SXiaojian Du 	switch (clk_type) {
886dd9e0b21SXiaojian Du 	case SMU_SOCCLK:
887dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_clk_limited(smu, clk_type,
888dd9e0b21SXiaojian Du 						soft_min_level, &min_freq);
889dd9e0b21SXiaojian Du 		if (ret)
890dd9e0b21SXiaojian Du 			return ret;
891dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_clk_limited(smu, clk_type,
892dd9e0b21SXiaojian Du 						soft_max_level, &max_freq);
893dd9e0b21SXiaojian Du 		if (ret)
894dd9e0b21SXiaojian Du 			return ret;
895dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
896dd9e0b21SXiaojian Du 								SMU_MSG_SetSoftMaxSocclkByFreq,
897dd9e0b21SXiaojian Du 								max_freq, NULL);
898dd9e0b21SXiaojian Du 		if (ret)
899dd9e0b21SXiaojian Du 			return ret;
900dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
901dd9e0b21SXiaojian Du 								SMU_MSG_SetHardMinSocclkByFreq,
902dd9e0b21SXiaojian Du 								min_freq, NULL);
903dd9e0b21SXiaojian Du 		if (ret)
904dd9e0b21SXiaojian Du 			return ret;
905dd9e0b21SXiaojian Du 		break;
906dd9e0b21SXiaojian Du 	case SMU_MCLK:
907dd9e0b21SXiaojian Du 	case SMU_FCLK:
908dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_clk_limited(smu,
909dd9e0b21SXiaojian Du 							clk_type, soft_min_level, &min_freq);
910dd9e0b21SXiaojian Du 		if (ret)
911dd9e0b21SXiaojian Du 			return ret;
912dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_clk_limited(smu,
913dd9e0b21SXiaojian Du 							clk_type, soft_max_level, &max_freq);
914dd9e0b21SXiaojian Du 		if (ret)
915dd9e0b21SXiaojian Du 			return ret;
916dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
917dd9e0b21SXiaojian Du 								SMU_MSG_SetSoftMaxFclkByFreq,
918dd9e0b21SXiaojian Du 								max_freq, NULL);
919dd9e0b21SXiaojian Du 		if (ret)
920dd9e0b21SXiaojian Du 			return ret;
921dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
922dd9e0b21SXiaojian Du 								SMU_MSG_SetHardMinFclkByFreq,
923dd9e0b21SXiaojian Du 								min_freq, NULL);
924dd9e0b21SXiaojian Du 		if (ret)
925dd9e0b21SXiaojian Du 			return ret;
926dd9e0b21SXiaojian Du 		break;
927dd9e0b21SXiaojian Du 	case SMU_VCLK:
928dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_clk_limited(smu,
929dd9e0b21SXiaojian Du 							clk_type, soft_min_level, &min_freq);
930dd9e0b21SXiaojian Du 		if (ret)
931dd9e0b21SXiaojian Du 			return ret;
932307f049bSXiaojian Du 
933dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_clk_limited(smu,
934dd9e0b21SXiaojian Du 							clk_type, soft_max_level, &max_freq);
935dd9e0b21SXiaojian Du 		if (ret)
936dd9e0b21SXiaojian Du 			return ret;
937307f049bSXiaojian Du 
938307f049bSXiaojian Du 
939dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
940dd9e0b21SXiaojian Du 								SMU_MSG_SetHardMinVcn,
941dd9e0b21SXiaojian Du 								min_freq << 16, NULL);
942dd9e0b21SXiaojian Du 		if (ret)
943dd9e0b21SXiaojian Du 			return ret;
944307f049bSXiaojian Du 
945307f049bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
946307f049bSXiaojian Du 								SMU_MSG_SetSoftMaxVcn,
947307f049bSXiaojian Du 								max_freq << 16, NULL);
948307f049bSXiaojian Du 		if (ret)
949307f049bSXiaojian Du 			return ret;
950307f049bSXiaojian Du 
951dd9e0b21SXiaojian Du 		break;
952dd9e0b21SXiaojian Du 	case SMU_DCLK:
953dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_clk_limited(smu,
954dd9e0b21SXiaojian Du 							clk_type, soft_min_level, &min_freq);
955dd9e0b21SXiaojian Du 		if (ret)
956dd9e0b21SXiaojian Du 			return ret;
957307f049bSXiaojian Du 
958dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_clk_limited(smu,
959dd9e0b21SXiaojian Du 							clk_type, soft_max_level, &max_freq);
960dd9e0b21SXiaojian Du 		if (ret)
961dd9e0b21SXiaojian Du 			return ret;
962307f049bSXiaojian Du 
963dd9e0b21SXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
964dd9e0b21SXiaojian Du 							SMU_MSG_SetHardMinVcn,
965dd9e0b21SXiaojian Du 							min_freq, NULL);
966dd9e0b21SXiaojian Du 		if (ret)
967dd9e0b21SXiaojian Du 			return ret;
968307f049bSXiaojian Du 
969307f049bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
970307f049bSXiaojian Du 							SMU_MSG_SetSoftMaxVcn,
971307f049bSXiaojian Du 							max_freq, NULL);
972307f049bSXiaojian Du 		if (ret)
973307f049bSXiaojian Du 			return ret;
974307f049bSXiaojian Du 
975dd9e0b21SXiaojian Du 		break;
976dd9e0b21SXiaojian Du 	default:
977dd9e0b21SXiaojian Du 		break;
978dd9e0b21SXiaojian Du 	}
979dd9e0b21SXiaojian Du 
980dd9e0b21SXiaojian Du 	return ret;
981dd9e0b21SXiaojian Du }
982dd9e0b21SXiaojian Du 
983dd9e0b21SXiaojian Du static int vangogh_force_dpm_limit_value(struct smu_context *smu, bool highest)
984dd9e0b21SXiaojian Du {
985dd9e0b21SXiaojian Du 	int ret = 0, i = 0;
986dd9e0b21SXiaojian Du 	uint32_t min_freq, max_freq, force_freq;
987dd9e0b21SXiaojian Du 	enum smu_clk_type clk_type;
988dd9e0b21SXiaojian Du 
989dd9e0b21SXiaojian Du 	enum smu_clk_type clks[] = {
990dd9e0b21SXiaojian Du 		SMU_SOCCLK,
991dd9e0b21SXiaojian Du 		SMU_VCLK,
992dd9e0b21SXiaojian Du 		SMU_DCLK,
993dd9e0b21SXiaojian Du 		SMU_MCLK,
994dd9e0b21SXiaojian Du 		SMU_FCLK,
995dd9e0b21SXiaojian Du 	};
996dd9e0b21SXiaojian Du 
997dd9e0b21SXiaojian Du 	for (i = 0; i < ARRAY_SIZE(clks); i++) {
998dd9e0b21SXiaojian Du 		clk_type = clks[i];
999dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_ultimate_freq(smu, clk_type, &min_freq, &max_freq);
1000dd9e0b21SXiaojian Du 		if (ret)
1001dd9e0b21SXiaojian Du 			return ret;
1002dd9e0b21SXiaojian Du 
1003dd9e0b21SXiaojian Du 		force_freq = highest ? max_freq : min_freq;
1004dd9e0b21SXiaojian Du 		ret = vangogh_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq);
1005dd9e0b21SXiaojian Du 		if (ret)
1006dd9e0b21SXiaojian Du 			return ret;
1007dd9e0b21SXiaojian Du 	}
1008dd9e0b21SXiaojian Du 
1009dd9e0b21SXiaojian Du 	return ret;
1010dd9e0b21SXiaojian Du }
1011dd9e0b21SXiaojian Du 
1012dd9e0b21SXiaojian Du static int vangogh_unforce_dpm_levels(struct smu_context *smu)
1013dd9e0b21SXiaojian Du {
1014dd9e0b21SXiaojian Du 	int ret = 0, i = 0;
1015dd9e0b21SXiaojian Du 	uint32_t min_freq, max_freq;
1016dd9e0b21SXiaojian Du 	enum smu_clk_type clk_type;
1017dd9e0b21SXiaojian Du 
1018dd9e0b21SXiaojian Du 	struct clk_feature_map {
1019dd9e0b21SXiaojian Du 		enum smu_clk_type clk_type;
1020dd9e0b21SXiaojian Du 		uint32_t	feature;
1021dd9e0b21SXiaojian Du 	} clk_feature_map[] = {
1022dd9e0b21SXiaojian Du 		{SMU_MCLK,   SMU_FEATURE_DPM_FCLK_BIT},
1023dd9e0b21SXiaojian Du 		{SMU_FCLK, SMU_FEATURE_DPM_FCLK_BIT},
1024dd9e0b21SXiaojian Du 		{SMU_SOCCLK, SMU_FEATURE_DPM_SOCCLK_BIT},
1025b0eec124SXiaojian Du 		{SMU_VCLK, SMU_FEATURE_VCN_DPM_BIT},
1026b0eec124SXiaojian Du 		{SMU_DCLK, SMU_FEATURE_VCN_DPM_BIT},
1027dd9e0b21SXiaojian Du 	};
1028dd9e0b21SXiaojian Du 
1029dd9e0b21SXiaojian Du 	for (i = 0; i < ARRAY_SIZE(clk_feature_map); i++) {
1030dd9e0b21SXiaojian Du 
1031dd9e0b21SXiaojian Du 		if (!smu_cmn_feature_is_enabled(smu, clk_feature_map[i].feature))
1032dd9e0b21SXiaojian Du 		    continue;
1033dd9e0b21SXiaojian Du 
1034dd9e0b21SXiaojian Du 		clk_type = clk_feature_map[i].clk_type;
1035dd9e0b21SXiaojian Du 
1036dd9e0b21SXiaojian Du 		ret = vangogh_get_dpm_ultimate_freq(smu, clk_type, &min_freq, &max_freq);
1037dd9e0b21SXiaojian Du 
1038dd9e0b21SXiaojian Du 		if (ret)
1039dd9e0b21SXiaojian Du 			return ret;
1040dd9e0b21SXiaojian Du 
1041dd9e0b21SXiaojian Du 		ret = vangogh_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
1042dd9e0b21SXiaojian Du 
1043dd9e0b21SXiaojian Du 		if (ret)
1044dd9e0b21SXiaojian Du 			return ret;
1045dd9e0b21SXiaojian Du 	}
1046dd9e0b21SXiaojian Du 
1047dd9e0b21SXiaojian Du 	return ret;
1048dd9e0b21SXiaojian Du }
1049dd9e0b21SXiaojian Du 
1050dd9e0b21SXiaojian Du static int vangogh_set_peak_clock_by_device(struct smu_context *smu)
1051dd9e0b21SXiaojian Du {
1052dd9e0b21SXiaojian Du 	int ret = 0;
1053dd9e0b21SXiaojian Du 	uint32_t socclk_freq = 0, fclk_freq = 0;
1054307f049bSXiaojian Du 	uint32_t vclk_freq = 0, dclk_freq = 0;
1055dd9e0b21SXiaojian Du 
1056dd9e0b21SXiaojian Du 	ret = vangogh_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_freq);
1057dd9e0b21SXiaojian Du 	if (ret)
1058dd9e0b21SXiaojian Du 		return ret;
1059dd9e0b21SXiaojian Du 
1060dd9e0b21SXiaojian Du 	ret = vangogh_set_soft_freq_limited_range(smu, SMU_FCLK, fclk_freq, fclk_freq);
1061dd9e0b21SXiaojian Du 	if (ret)
1062dd9e0b21SXiaojian Du 		return ret;
1063dd9e0b21SXiaojian Du 
1064dd9e0b21SXiaojian Du 	ret = vangogh_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_freq);
1065dd9e0b21SXiaojian Du 	if (ret)
1066dd9e0b21SXiaojian Du 		return ret;
1067dd9e0b21SXiaojian Du 
1068dd9e0b21SXiaojian Du 	ret = vangogh_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk_freq, socclk_freq);
1069dd9e0b21SXiaojian Du 	if (ret)
1070dd9e0b21SXiaojian Du 		return ret;
1071dd9e0b21SXiaojian Du 
1072307f049bSXiaojian Du 	ret = vangogh_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &vclk_freq);
1073307f049bSXiaojian Du 	if (ret)
1074307f049bSXiaojian Du 		return ret;
1075307f049bSXiaojian Du 
1076307f049bSXiaojian Du 	ret = vangogh_set_soft_freq_limited_range(smu, SMU_VCLK, vclk_freq, vclk_freq);
1077307f049bSXiaojian Du 	if (ret)
1078307f049bSXiaojian Du 		return ret;
1079307f049bSXiaojian Du 
1080307f049bSXiaojian Du 	ret = vangogh_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &dclk_freq);
1081307f049bSXiaojian Du 	if (ret)
1082307f049bSXiaojian Du 		return ret;
1083307f049bSXiaojian Du 
1084307f049bSXiaojian Du 	ret = vangogh_set_soft_freq_limited_range(smu, SMU_DCLK, dclk_freq, dclk_freq);
1085307f049bSXiaojian Du 	if (ret)
1086307f049bSXiaojian Du 		return ret;
1087307f049bSXiaojian Du 
1088dd9e0b21SXiaojian Du 	return ret;
1089dd9e0b21SXiaojian Du }
1090dd9e0b21SXiaojian Du 
1091ea173d15SXiaojian Du static int vangogh_set_performance_level(struct smu_context *smu,
1092ea173d15SXiaojian Du 					enum amd_dpm_forced_level level)
1093ea173d15SXiaojian Du {
1094ea173d15SXiaojian Du 	int ret = 0;
1095ea173d15SXiaojian Du 	uint32_t soc_mask, mclk_mask, fclk_mask;
1096307f049bSXiaojian Du 	uint32_t vclk_mask = 0, dclk_mask = 0;
1097ea173d15SXiaojian Du 
1098ea173d15SXiaojian Du 	switch (level) {
1099ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_HIGH:
1100ea173d15SXiaojian Du 		ret = vangogh_force_dpm_limit_value(smu, true);
1101ea173d15SXiaojian Du 		break;
1102ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_LOW:
1103ea173d15SXiaojian Du 		ret = vangogh_force_dpm_limit_value(smu, false);
1104ea173d15SXiaojian Du 		break;
1105ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_AUTO:
1106ea173d15SXiaojian Du 		ret = vangogh_unforce_dpm_levels(smu);
1107ea173d15SXiaojian Du 		break;
1108ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1109307f049bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
1110307f049bSXiaojian Du 					SMU_MSG_SetHardMinGfxClk,
1111307f049bSXiaojian Du 					VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, NULL);
1112307f049bSXiaojian Du 		if (ret)
1113307f049bSXiaojian Du 			return ret;
1114307f049bSXiaojian Du 
1115307f049bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu,
1116307f049bSXiaojian Du 					SMU_MSG_SetSoftMaxGfxClk,
1117307f049bSXiaojian Du 					VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, NULL);
1118307f049bSXiaojian Du 		if (ret)
1119307f049bSXiaojian Du 			return ret;
1120307f049bSXiaojian Du 
1121307f049bSXiaojian Du 		ret = vangogh_get_profiling_clk_mask(smu, level,
1122307f049bSXiaojian Du 							&vclk_mask,
1123307f049bSXiaojian Du 							&dclk_mask,
1124307f049bSXiaojian Du 							&mclk_mask,
1125307f049bSXiaojian Du 							&fclk_mask,
1126307f049bSXiaojian Du 							&soc_mask);
1127307f049bSXiaojian Du 		if (ret)
1128307f049bSXiaojian Du 			return ret;
1129307f049bSXiaojian Du 
1130307f049bSXiaojian Du 		vangogh_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask);
1131307f049bSXiaojian Du 		vangogh_force_clk_levels(smu, SMU_FCLK, 1 << fclk_mask);
1132307f049bSXiaojian Du 		vangogh_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
1133307f049bSXiaojian Du 		vangogh_force_clk_levels(smu, SMU_VCLK, 1 << vclk_mask);
1134307f049bSXiaojian Du 		vangogh_force_clk_levels(smu, SMU_DCLK, 1 << dclk_mask);
1135307f049bSXiaojian Du 
1136ea173d15SXiaojian Du 		break;
1137ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1138307f049bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinVcn,
1139307f049bSXiaojian Du 								VANGOGH_UMD_PSTATE_PEAK_DCLK, NULL);
1140307f049bSXiaojian Du 		if (ret)
1141307f049bSXiaojian Du 			return ret;
1142307f049bSXiaojian Du 
1143307f049bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxVcn,
1144307f049bSXiaojian Du 								VANGOGH_UMD_PSTATE_PEAK_DCLK, NULL);
1145307f049bSXiaojian Du 		if (ret)
1146307f049bSXiaojian Du 			return ret;
1147ea173d15SXiaojian Du 		break;
1148ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1149ea173d15SXiaojian Du 		ret = vangogh_get_profiling_clk_mask(smu, level,
1150ea173d15SXiaojian Du 							NULL,
1151ea173d15SXiaojian Du 							NULL,
1152ea173d15SXiaojian Du 							&mclk_mask,
1153ea173d15SXiaojian Du 							&fclk_mask,
1154307f049bSXiaojian Du 							NULL);
1155ea173d15SXiaojian Du 		if (ret)
1156ea173d15SXiaojian Du 			return ret;
1157307f049bSXiaojian Du 
1158ea173d15SXiaojian Du 		vangogh_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask);
1159ea173d15SXiaojian Du 		vangogh_force_clk_levels(smu, SMU_FCLK, 1 << fclk_mask);
1160ea173d15SXiaojian Du 		break;
1161ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1162307f049bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
1163307f049bSXiaojian Du 				VANGOGH_UMD_PSTATE_PEAK_GFXCLK, NULL);
1164307f049bSXiaojian Du 		if (ret)
1165307f049bSXiaojian Du 			return ret;
1166307f049bSXiaojian Du 
1167307f049bSXiaojian Du 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
1168307f049bSXiaojian Du 				VANGOGH_UMD_PSTATE_PEAK_GFXCLK, NULL);
1169307f049bSXiaojian Du 		if (ret)
1170307f049bSXiaojian Du 			return ret;
1171307f049bSXiaojian Du 
1172ea173d15SXiaojian Du 		ret = vangogh_set_peak_clock_by_device(smu);
1173ea173d15SXiaojian Du 		break;
1174ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_MANUAL:
1175ea173d15SXiaojian Du 	case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
1176ea173d15SXiaojian Du 	default:
1177ea173d15SXiaojian Du 		break;
1178ea173d15SXiaojian Du 	}
1179ea173d15SXiaojian Du 	return ret;
1180ea173d15SXiaojian Du }
1181ea173d15SXiaojian Du 
1182271ab489SXiaojian Du static int vangogh_read_sensor(struct smu_context *smu,
1183271ab489SXiaojian Du 				 enum amd_pp_sensors sensor,
1184271ab489SXiaojian Du 				 void *data, uint32_t *size)
1185271ab489SXiaojian Du {
1186271ab489SXiaojian Du 	int ret = 0;
1187271ab489SXiaojian Du 
1188271ab489SXiaojian Du 	if (!data || !size)
1189271ab489SXiaojian Du 		return -EINVAL;
1190271ab489SXiaojian Du 
1191271ab489SXiaojian Du 	mutex_lock(&smu->sensor_lock);
1192271ab489SXiaojian Du 	switch (sensor) {
1193271ab489SXiaojian Du 	case AMDGPU_PP_SENSOR_GPU_LOAD:
11946cc24d8dSAlex Deucher 		ret = vangogh_get_smu_metrics_data(smu,
11956cc24d8dSAlex Deucher 						   METRICS_AVERAGE_GFXACTIVITY,
11966cc24d8dSAlex Deucher 						   (uint32_t *)data);
1197271ab489SXiaojian Du 		*size = 4;
1198271ab489SXiaojian Du 		break;
1199271ab489SXiaojian Du 	case AMDGPU_PP_SENSOR_GPU_POWER:
12006cc24d8dSAlex Deucher 		ret = vangogh_get_smu_metrics_data(smu,
12016cc24d8dSAlex Deucher 						   METRICS_AVERAGE_SOCKETPOWER,
12026cc24d8dSAlex Deucher 						   (uint32_t *)data);
1203271ab489SXiaojian Du 		*size = 4;
1204271ab489SXiaojian Du 		break;
1205271ab489SXiaojian Du 	case AMDGPU_PP_SENSOR_EDGE_TEMP:
12066cc24d8dSAlex Deucher 		ret = vangogh_get_smu_metrics_data(smu,
12076cc24d8dSAlex Deucher 						   METRICS_TEMPERATURE_EDGE,
12086cc24d8dSAlex Deucher 						   (uint32_t *)data);
12096cc24d8dSAlex Deucher 		*size = 4;
12106cc24d8dSAlex Deucher 		break;
1211271ab489SXiaojian Du 	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
12126cc24d8dSAlex Deucher 		ret = vangogh_get_smu_metrics_data(smu,
12136cc24d8dSAlex Deucher 						   METRICS_TEMPERATURE_HOTSPOT,
12146cc24d8dSAlex Deucher 						   (uint32_t *)data);
1215271ab489SXiaojian Du 		*size = 4;
1216271ab489SXiaojian Du 		break;
1217271ab489SXiaojian Du 	case AMDGPU_PP_SENSOR_GFX_MCLK:
12186cc24d8dSAlex Deucher 		ret = vangogh_get_smu_metrics_data(smu,
12196cc24d8dSAlex Deucher 						   METRICS_AVERAGE_UCLK,
12206cc24d8dSAlex Deucher 						   (uint32_t *)data);
1221271ab489SXiaojian Du 		*(uint32_t *)data *= 100;
1222271ab489SXiaojian Du 		*size = 4;
1223271ab489SXiaojian Du 		break;
1224271ab489SXiaojian Du 	case AMDGPU_PP_SENSOR_GFX_SCLK:
12256cc24d8dSAlex Deucher 		ret = vangogh_get_smu_metrics_data(smu,
12266cc24d8dSAlex Deucher 						   METRICS_AVERAGE_GFXCLK,
12276cc24d8dSAlex Deucher 						   (uint32_t *)data);
1228271ab489SXiaojian Du 		*(uint32_t *)data *= 100;
1229271ab489SXiaojian Du 		*size = 4;
1230271ab489SXiaojian Du 		break;
1231271ab489SXiaojian Du 	case AMDGPU_PP_SENSOR_VDDGFX:
12322139d12bSAlex Deucher 		ret = vangogh_get_smu_metrics_data(smu,
12332139d12bSAlex Deucher 						   METRICS_VOLTAGE_VDDGFX,
12342139d12bSAlex Deucher 						   (uint32_t *)data);
12352139d12bSAlex Deucher 		*size = 4;
12362139d12bSAlex Deucher 		break;
12372139d12bSAlex Deucher 	case AMDGPU_PP_SENSOR_VDDNB:
12382139d12bSAlex Deucher 		ret = vangogh_get_smu_metrics_data(smu,
12392139d12bSAlex Deucher 						   METRICS_VOLTAGE_VDDSOC,
12402139d12bSAlex Deucher 						   (uint32_t *)data);
1241271ab489SXiaojian Du 		*size = 4;
1242271ab489SXiaojian Du 		break;
1243271ab489SXiaojian Du 	default:
1244271ab489SXiaojian Du 		ret = -EOPNOTSUPP;
1245271ab489SXiaojian Du 		break;
1246271ab489SXiaojian Du 	}
1247271ab489SXiaojian Du 	mutex_unlock(&smu->sensor_lock);
1248271ab489SXiaojian Du 
1249271ab489SXiaojian Du 	return ret;
1250271ab489SXiaojian Du }
1251271ab489SXiaojian Du 
1252271ab489SXiaojian Du static int vangogh_set_watermarks_table(struct smu_context *smu,
1253271ab489SXiaojian Du 				       struct pp_smu_wm_range_sets *clock_ranges)
1254271ab489SXiaojian Du {
1255271ab489SXiaojian Du 	int i;
1256271ab489SXiaojian Du 	int ret = 0;
1257271ab489SXiaojian Du 	Watermarks_t *table = smu->smu_table.watermarks_table;
1258271ab489SXiaojian Du 
1259271ab489SXiaojian Du 	if (!table || !clock_ranges)
1260271ab489SXiaojian Du 		return -EINVAL;
1261271ab489SXiaojian Du 
1262271ab489SXiaojian Du 	if (clock_ranges) {
1263271ab489SXiaojian Du 		if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES ||
1264271ab489SXiaojian Du 			clock_ranges->num_writer_wm_sets > NUM_WM_RANGES)
1265271ab489SXiaojian Du 			return -EINVAL;
1266271ab489SXiaojian Du 
1267271ab489SXiaojian Du 		for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
1268271ab489SXiaojian Du 			table->WatermarkRow[WM_DCFCLK][i].MinClock =
1269271ab489SXiaojian Du 				clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
1270271ab489SXiaojian Du 			table->WatermarkRow[WM_DCFCLK][i].MaxClock =
1271271ab489SXiaojian Du 				clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
1272271ab489SXiaojian Du 			table->WatermarkRow[WM_DCFCLK][i].MinMclk =
1273271ab489SXiaojian Du 				clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
1274271ab489SXiaojian Du 			table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
1275271ab489SXiaojian Du 				clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
1276271ab489SXiaojian Du 
1277271ab489SXiaojian Du 			table->WatermarkRow[WM_DCFCLK][i].WmSetting =
1278271ab489SXiaojian Du 				clock_ranges->reader_wm_sets[i].wm_inst;
1279271ab489SXiaojian Du 		}
1280271ab489SXiaojian Du 
1281271ab489SXiaojian Du 		for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
1282271ab489SXiaojian Du 			table->WatermarkRow[WM_SOCCLK][i].MinClock =
1283271ab489SXiaojian Du 				clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
1284271ab489SXiaojian Du 			table->WatermarkRow[WM_SOCCLK][i].MaxClock =
1285271ab489SXiaojian Du 				clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
1286271ab489SXiaojian Du 			table->WatermarkRow[WM_SOCCLK][i].MinMclk =
1287271ab489SXiaojian Du 				clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
1288271ab489SXiaojian Du 			table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
1289271ab489SXiaojian Du 				clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
1290271ab489SXiaojian Du 
1291271ab489SXiaojian Du 			table->WatermarkRow[WM_SOCCLK][i].WmSetting =
1292271ab489SXiaojian Du 				clock_ranges->writer_wm_sets[i].wm_inst;
1293271ab489SXiaojian Du 		}
1294271ab489SXiaojian Du 
1295271ab489SXiaojian Du 		smu->watermarks_bitmap |= WATERMARKS_EXIST;
1296271ab489SXiaojian Du 	}
1297271ab489SXiaojian Du 
1298271ab489SXiaojian Du 	/* pass data to smu controller */
1299271ab489SXiaojian Du 	if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
1300271ab489SXiaojian Du 	     !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
1301271ab489SXiaojian Du 		ret = smu_cmn_write_watermarks_table(smu);
1302271ab489SXiaojian Du 		if (ret) {
1303271ab489SXiaojian Du 			dev_err(smu->adev->dev, "Failed to update WMTABLE!");
1304271ab489SXiaojian Du 			return ret;
1305271ab489SXiaojian Du 		}
1306271ab489SXiaojian Du 		smu->watermarks_bitmap |= WATERMARKS_LOADED;
1307271ab489SXiaojian Du 	}
1308271ab489SXiaojian Du 
1309271ab489SXiaojian Du 	return 0;
1310f46a221bSXiaojian Du }
1311f46a221bSXiaojian Du 
1312fd253334SXiaojian Du static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu,
1313fd253334SXiaojian Du 				      void **table)
1314fd253334SXiaojian Du {
1315fd253334SXiaojian Du 	struct smu_table_context *smu_table = &smu->smu_table;
1316fd253334SXiaojian Du 	struct gpu_metrics_v2_0 *gpu_metrics =
1317fd253334SXiaojian Du 		(struct gpu_metrics_v2_0 *)smu_table->gpu_metrics_table;
1318fd253334SXiaojian Du 	SmuMetrics_t metrics;
1319fd253334SXiaojian Du 	int ret = 0;
1320fd253334SXiaojian Du 
1321fd253334SXiaojian Du 	ret = smu_cmn_get_metrics_table(smu, &metrics, true);
1322fd253334SXiaojian Du 	if (ret)
1323fd253334SXiaojian Du 		return ret;
1324fd253334SXiaojian Du 
1325fd253334SXiaojian Du 	smu_v11_0_init_gpu_metrics_v2_0(gpu_metrics);
1326fd253334SXiaojian Du 
1327fd253334SXiaojian Du 	gpu_metrics->temperature_gfx = metrics.GfxTemperature;
1328fd253334SXiaojian Du 	gpu_metrics->temperature_soc = metrics.SocTemperature;
1329fd253334SXiaojian Du 	memcpy(&gpu_metrics->temperature_core[0],
1330fd253334SXiaojian Du 		&metrics.CoreTemperature[0],
1331fd253334SXiaojian Du 		sizeof(uint16_t) * 8);
1332fd253334SXiaojian Du 	gpu_metrics->temperature_l3[0] = metrics.L3Temperature[0];
1333fd253334SXiaojian Du 	gpu_metrics->temperature_l3[1] = metrics.L3Temperature[1];
1334fd253334SXiaojian Du 
1335fd253334SXiaojian Du 	gpu_metrics->average_gfx_activity = metrics.GfxActivity;
1336fd253334SXiaojian Du 	gpu_metrics->average_mm_activity = metrics.UvdActivity;
1337fd253334SXiaojian Du 
1338fd253334SXiaojian Du 	gpu_metrics->average_socket_power = metrics.CurrentSocketPower;
1339fd253334SXiaojian Du 	gpu_metrics->average_cpu_power = metrics.Power[0];
1340fd253334SXiaojian Du 	gpu_metrics->average_soc_power = metrics.Power[1];
1341fd253334SXiaojian Du 	memcpy(&gpu_metrics->average_core_power[0],
1342fd253334SXiaojian Du 		&metrics.CorePower[0],
1343fd253334SXiaojian Du 		sizeof(uint16_t) * 8);
1344fd253334SXiaojian Du 
1345fd253334SXiaojian Du 	gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency;
1346fd253334SXiaojian Du 	gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency;
1347fd253334SXiaojian Du 	gpu_metrics->average_fclk_frequency = metrics.MemclkFrequency;
1348fd253334SXiaojian Du 	gpu_metrics->average_vclk_frequency = metrics.VclkFrequency;
1349fd253334SXiaojian Du 
1350fd253334SXiaojian Du 	memcpy(&gpu_metrics->current_coreclk[0],
1351fd253334SXiaojian Du 		&metrics.CoreFrequency[0],
1352fd253334SXiaojian Du 		sizeof(uint16_t) * 8);
1353fd253334SXiaojian Du 	gpu_metrics->current_l3clk[0] = metrics.L3Frequency[0];
1354fd253334SXiaojian Du 	gpu_metrics->current_l3clk[1] = metrics.L3Frequency[1];
1355fd253334SXiaojian Du 
1356fd253334SXiaojian Du 	gpu_metrics->throttle_status = metrics.ThrottlerStatus;
1357fd253334SXiaojian Du 
1358fd253334SXiaojian Du 	*table = (void *)gpu_metrics;
1359fd253334SXiaojian Du 
1360fd253334SXiaojian Du 	return sizeof(struct gpu_metrics_v2_0);
1361fd253334SXiaojian Du }
1362fd253334SXiaojian Du 
1363c98ee897SXiaojian Du static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type,
1364c98ee897SXiaojian Du 							long input[], uint32_t size)
1365c98ee897SXiaojian Du {
1366c98ee897SXiaojian Du 	int ret = 0;
1367c98ee897SXiaojian Du 
1368c98ee897SXiaojian Du 	if (!smu->od_enabled) {
1369c98ee897SXiaojian Du 		dev_warn(smu->adev->dev, "Fine grain is not enabled!\n");
1370c98ee897SXiaojian Du 		return -EINVAL;
1371c98ee897SXiaojian Du 	}
1372c98ee897SXiaojian Du 
1373c98ee897SXiaojian Du 	switch (type) {
1374c98ee897SXiaojian Du 	case PP_OD_EDIT_SCLK_VDDC_TABLE:
1375c98ee897SXiaojian Du 		if (size != 2) {
1376c98ee897SXiaojian Du 			dev_err(smu->adev->dev, "Input parameter number not correct\n");
1377c98ee897SXiaojian Du 			return -EINVAL;
1378c98ee897SXiaojian Du 		}
1379c98ee897SXiaojian Du 
1380c98ee897SXiaojian Du 		if (input[0] == 0) {
1381c98ee897SXiaojian Du 			if (input[1] < smu->gfx_default_hard_min_freq) {
1382307f049bSXiaojian Du 				dev_warn(smu->adev->dev,
1383307f049bSXiaojian Du 					"Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
1384c98ee897SXiaojian Du 					input[1], smu->gfx_default_hard_min_freq);
1385c98ee897SXiaojian Du 				return -EINVAL;
1386c98ee897SXiaojian Du 			}
1387c98ee897SXiaojian Du 			smu->gfx_actual_hard_min_freq = input[1];
1388c98ee897SXiaojian Du 		} else if (input[0] == 1) {
1389c98ee897SXiaojian Du 			if (input[1] > smu->gfx_default_soft_max_freq) {
1390307f049bSXiaojian Du 				dev_warn(smu->adev->dev,
1391307f049bSXiaojian Du 					"Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
1392c98ee897SXiaojian Du 					input[1], smu->gfx_default_soft_max_freq);
1393c98ee897SXiaojian Du 				return -EINVAL;
1394c98ee897SXiaojian Du 			}
1395c98ee897SXiaojian Du 			smu->gfx_actual_soft_max_freq = input[1];
1396c98ee897SXiaojian Du 		} else {
1397c98ee897SXiaojian Du 			return -EINVAL;
1398c98ee897SXiaojian Du 		}
1399c98ee897SXiaojian Du 		break;
1400c98ee897SXiaojian Du 	case PP_OD_RESTORE_DEFAULT_TABLE:
1401c98ee897SXiaojian Du 		if (size != 0) {
1402c98ee897SXiaojian Du 			dev_err(smu->adev->dev, "Input parameter number not correct\n");
1403c98ee897SXiaojian Du 			return -EINVAL;
1404c98ee897SXiaojian Du 		} else {
1405c98ee897SXiaojian Du 			smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
1406c98ee897SXiaojian Du 			smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
1407c98ee897SXiaojian Du 
1408c98ee897SXiaojian Du 			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
1409c98ee897SXiaojian Du 									smu->gfx_actual_hard_min_freq, NULL);
1410c98ee897SXiaojian Du 			if (ret) {
1411c98ee897SXiaojian Du 				dev_err(smu->adev->dev, "Restore the default hard min sclk failed!");
1412c98ee897SXiaojian Du 				return ret;
1413c98ee897SXiaojian Du 			}
1414c98ee897SXiaojian Du 
1415c98ee897SXiaojian Du 			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
1416c98ee897SXiaojian Du 									smu->gfx_actual_soft_max_freq, NULL);
1417c98ee897SXiaojian Du 			if (ret) {
1418c98ee897SXiaojian Du 				dev_err(smu->adev->dev, "Restore the default soft max sclk failed!");
1419c98ee897SXiaojian Du 				return ret;
1420c98ee897SXiaojian Du 			}
1421c98ee897SXiaojian Du 		}
1422c98ee897SXiaojian Du 		break;
1423c98ee897SXiaojian Du 	case PP_OD_COMMIT_DPM_TABLE:
1424c98ee897SXiaojian Du 		if (size != 0) {
1425c98ee897SXiaojian Du 			dev_err(smu->adev->dev, "Input parameter number not correct\n");
1426c98ee897SXiaojian Du 			return -EINVAL;
1427c98ee897SXiaojian Du 		} else {
1428c98ee897SXiaojian Du 			if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) {
1429307f049bSXiaojian Du 				dev_err(smu->adev->dev,
1430307f049bSXiaojian Du 					"The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
1431307f049bSXiaojian Du 					smu->gfx_actual_hard_min_freq,
1432307f049bSXiaojian Du 					smu->gfx_actual_soft_max_freq);
1433c98ee897SXiaojian Du 				return -EINVAL;
1434c98ee897SXiaojian Du 			}
1435c98ee897SXiaojian Du 
1436c98ee897SXiaojian Du 			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
1437c98ee897SXiaojian Du 									smu->gfx_actual_hard_min_freq, NULL);
1438c98ee897SXiaojian Du 			if (ret) {
1439c98ee897SXiaojian Du 				dev_err(smu->adev->dev, "Set hard min sclk failed!");
1440c98ee897SXiaojian Du 				return ret;
1441c98ee897SXiaojian Du 			}
1442c98ee897SXiaojian Du 
1443c98ee897SXiaojian Du 			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
1444c98ee897SXiaojian Du 									smu->gfx_actual_soft_max_freq, NULL);
1445c98ee897SXiaojian Du 			if (ret) {
1446c98ee897SXiaojian Du 				dev_err(smu->adev->dev, "Set soft max sclk failed!");
1447c98ee897SXiaojian Du 				return ret;
1448c98ee897SXiaojian Du 			}
1449c98ee897SXiaojian Du 		}
1450c98ee897SXiaojian Du 		break;
1451c98ee897SXiaojian Du 	default:
1452c98ee897SXiaojian Du 		return -ENOSYS;
1453c98ee897SXiaojian Du 	}
1454c98ee897SXiaojian Du 
1455c98ee897SXiaojian Du 	return ret;
1456c98ee897SXiaojian Du }
1457c98ee897SXiaojian Du 
1458fce8a4acSJinzhou Su static int vangogh_set_default_dpm_tables(struct smu_context *smu)
1459c98ee897SXiaojian Du {
1460c98ee897SXiaojian Du 	struct smu_table_context *smu_table = &smu->smu_table;
1461c98ee897SXiaojian Du 
1462c98ee897SXiaojian Du 	return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false);
1463c98ee897SXiaojian Du }
1464c98ee897SXiaojian Du 
1465c98ee897SXiaojian Du static int vangogh_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
1466c98ee897SXiaojian Du {
1467c98ee897SXiaojian Du 	DpmClocks_t *clk_table = smu->smu_table.clocks_table;
1468c98ee897SXiaojian Du 
1469c98ee897SXiaojian Du 	smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
1470c98ee897SXiaojian Du 	smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
1471c98ee897SXiaojian Du 	smu->gfx_actual_hard_min_freq = 0;
1472c98ee897SXiaojian Du 	smu->gfx_actual_soft_max_freq = 0;
1473c98ee897SXiaojian Du 
1474c98ee897SXiaojian Du 	return 0;
1475c98ee897SXiaojian Du }
1476c98ee897SXiaojian Du 
1477ae7b32e7SXiaojian Du static int vangogh_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks *clock_table)
1478ae7b32e7SXiaojian Du {
1479ae7b32e7SXiaojian Du 	DpmClocks_t *table = smu->smu_table.clocks_table;
1480ae7b32e7SXiaojian Du 	int i;
1481ae7b32e7SXiaojian Du 
1482ae7b32e7SXiaojian Du 	if (!clock_table || !table)
1483ae7b32e7SXiaojian Du 		return -EINVAL;
1484ae7b32e7SXiaojian Du 
1485ae7b32e7SXiaojian Du 	for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) {
1486ae7b32e7SXiaojian Du 		clock_table->SocClocks[i].Freq = table->SocClocks[i];
1487ae7b32e7SXiaojian Du 		clock_table->SocClocks[i].Vol = table->SocVoltage[i];
1488ae7b32e7SXiaojian Du 	}
1489ae7b32e7SXiaojian Du 
1490ae7b32e7SXiaojian Du 	for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) {
1491ae7b32e7SXiaojian Du 		clock_table->FClocks[i].Freq = table->DfPstateTable[i].fclk;
1492ae7b32e7SXiaojian Du 		clock_table->FClocks[i].Vol = table->DfPstateTable[i].voltage;
1493ae7b32e7SXiaojian Du 	}
1494ae7b32e7SXiaojian Du 
1495ae7b32e7SXiaojian Du 	for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) {
1496ae7b32e7SXiaojian Du 		clock_table->MemClocks[i].Freq = table->DfPstateTable[i].memclk;
1497ae7b32e7SXiaojian Du 		clock_table->MemClocks[i].Vol = table->DfPstateTable[i].voltage;
1498ae7b32e7SXiaojian Du 	}
1499ae7b32e7SXiaojian Du 
1500ae7b32e7SXiaojian Du 	return 0;
1501ae7b32e7SXiaojian Du }
1502ae7b32e7SXiaojian Du 
1503ae7b32e7SXiaojian Du 
1504a0f55287SXiaomeng Hou static int vangogh_system_features_control(struct smu_context *smu, bool en)
1505a0f55287SXiaomeng Hou {
15069e3a6ab7SXiaomeng Hou 	struct amdgpu_device *adev = smu->adev;
1507aedebd40SHuang Rui 	struct smu_feature *feature = &smu->smu_feature;
1508aedebd40SHuang Rui 	uint32_t feature_mask[2];
1509aedebd40SHuang Rui 	int ret = 0;
15109e3a6ab7SXiaomeng Hou 
15119e3a6ab7SXiaomeng Hou 	if (adev->pm.fw_version >= 0x43f1700)
1512aedebd40SHuang Rui 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_RlcPowerNotify,
1513a0f55287SXiaomeng Hou 						      en ? RLC_STATUS_NORMAL : RLC_STATUS_OFF, NULL);
1514aedebd40SHuang Rui 
1515aedebd40SHuang Rui 	bitmap_zero(feature->enabled, feature->feature_num);
1516aedebd40SHuang Rui 	bitmap_zero(feature->supported, feature->feature_num);
1517aedebd40SHuang Rui 
1518aedebd40SHuang Rui 	if (!en)
1519aedebd40SHuang Rui 		return ret;
1520aedebd40SHuang Rui 
1521aedebd40SHuang Rui 	ret = smu_cmn_get_enabled_32_bits_mask(smu, feature_mask, 2);
1522aedebd40SHuang Rui 	if (ret)
1523aedebd40SHuang Rui 		return ret;
1524aedebd40SHuang Rui 
1525aedebd40SHuang Rui 	bitmap_copy(feature->enabled, (unsigned long *)&feature_mask,
1526aedebd40SHuang Rui 		    feature->feature_num);
1527aedebd40SHuang Rui 	bitmap_copy(feature->supported, (unsigned long *)&feature_mask,
1528aedebd40SHuang Rui 		    feature->feature_num);
1529aedebd40SHuang Rui 
15309e3a6ab7SXiaomeng Hou 	return 0;
1531a0f55287SXiaomeng Hou }
1532a0f55287SXiaomeng Hou 
1533eefdf047SJinzhou Su static int vangogh_post_smu_init(struct smu_context *smu)
1534eefdf047SJinzhou Su {
1535eefdf047SJinzhou Su 	struct amdgpu_device *adev = smu->adev;
1536eefdf047SJinzhou Su 	uint32_t tmp;
1537eefdf047SJinzhou Su 	uint8_t aon_bits = 0;
1538eefdf047SJinzhou Su 	/* Two CUs in one WGP */
1539eefdf047SJinzhou Su 	uint32_t req_active_wgps = adev->gfx.cu_info.number/2;
1540eefdf047SJinzhou Su 	uint32_t total_cu = adev->gfx.config.max_cu_per_sh *
1541eefdf047SJinzhou Su 		adev->gfx.config.max_sh_per_se * adev->gfx.config.max_shader_engines;
1542eefdf047SJinzhou Su 
1543eefdf047SJinzhou Su 	/* if all CUs are active, no need to power off any WGPs */
1544eefdf047SJinzhou Su 	if (total_cu == adev->gfx.cu_info.number)
1545eefdf047SJinzhou Su 		return 0;
1546eefdf047SJinzhou Su 
1547eefdf047SJinzhou Su 	/*
1548eefdf047SJinzhou Su 	 * Calculate the total bits number of always on WGPs for all SA/SEs in
1549eefdf047SJinzhou Su 	 * RLC_PG_ALWAYS_ON_WGP_MASK.
1550eefdf047SJinzhou Su 	 */
1551eefdf047SJinzhou Su 	tmp = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_ALWAYS_ON_WGP_MASK));
1552eefdf047SJinzhou Su 	tmp &= RLC_PG_ALWAYS_ON_WGP_MASK__AON_WGP_MASK_MASK;
1553eefdf047SJinzhou Su 
1554eefdf047SJinzhou Su 	aon_bits = hweight32(tmp) * adev->gfx.config.max_sh_per_se * adev->gfx.config.max_shader_engines;
1555eefdf047SJinzhou Su 
1556eefdf047SJinzhou Su 	/* Do not request any WGPs less than set in the AON_WGP_MASK */
1557eefdf047SJinzhou Su 	if (aon_bits > req_active_wgps) {
1558eefdf047SJinzhou Su 		dev_info(adev->dev, "Number of always on WGPs greater than active WGPs: WGP power save not requested.\n");
1559eefdf047SJinzhou Su 		return 0;
1560eefdf047SJinzhou Su 	} else {
1561eefdf047SJinzhou Su 		return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_RequestActiveWgp, req_active_wgps, NULL);
1562eefdf047SJinzhou Su 	}
1563eefdf047SJinzhou Su }
1564eefdf047SJinzhou Su 
1565*20e157c7SAlex Deucher static int vangogh_mode2_reset(struct smu_context *smu)
1566*20e157c7SAlex Deucher {
1567*20e157c7SAlex Deucher 	return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, SMU_RESET_MODE_2, NULL);
1568*20e157c7SAlex Deucher }
1569*20e157c7SAlex Deucher 
1570f46a221bSXiaojian Du static const struct pptable_funcs vangogh_ppt_funcs = {
1571271ab489SXiaojian Du 
1572f46a221bSXiaojian Du 	.check_fw_status = smu_v11_0_check_fw_status,
1573f46a221bSXiaojian Du 	.check_fw_version = smu_v11_0_check_fw_version,
1574f46a221bSXiaojian Du 	.init_smc_tables = vangogh_init_smc_tables,
1575f46a221bSXiaojian Du 	.fini_smc_tables = smu_v11_0_fini_smc_tables,
1576f46a221bSXiaojian Du 	.init_power = smu_v11_0_init_power,
1577f46a221bSXiaojian Du 	.fini_power = smu_v11_0_fini_power,
1578f46a221bSXiaojian Du 	.register_irq_handler = smu_v11_0_register_irq_handler,
1579f46a221bSXiaojian Du 	.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
1580f46a221bSXiaojian Du 	.send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
1581f46a221bSXiaojian Du 	.send_smc_msg = smu_cmn_send_smc_msg,
1582271ab489SXiaojian Du 	.dpm_set_vcn_enable = vangogh_dpm_set_vcn_enable,
1583271ab489SXiaojian Du 	.dpm_set_jpeg_enable = vangogh_dpm_set_jpeg_enable,
1584f46a221bSXiaojian Du 	.is_dpm_running = vangogh_is_dpm_running,
1585271ab489SXiaojian Du 	.read_sensor = vangogh_read_sensor,
1586271ab489SXiaojian Du 	.get_enabled_mask = smu_cmn_get_enabled_32_bits_mask,
1587f46a221bSXiaojian Du 	.get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
1588271ab489SXiaojian Du 	.set_watermarks_table = vangogh_set_watermarks_table,
1589271ab489SXiaojian Du 	.set_driver_table_location = smu_v11_0_set_driver_table_location,
1590f46a221bSXiaojian Du 	.interrupt_work = smu_v11_0_interrupt_work,
1591fd253334SXiaojian Du 	.get_gpu_metrics = vangogh_get_gpu_metrics,
1592c98ee897SXiaojian Du 	.od_edit_dpm_table = vangogh_od_edit_dpm_table,
1593c98ee897SXiaojian Du 	.print_clk_levels = vangogh_print_fine_grain_clk,
1594c98ee897SXiaojian Du 	.set_default_dpm_table = vangogh_set_default_dpm_tables,
1595c98ee897SXiaojian Du 	.set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters,
1596a0f55287SXiaomeng Hou 	.system_features_control = vangogh_system_features_control,
1597d0e4e112SXiaojian Du 	.feature_is_enabled = smu_cmn_feature_is_enabled,
1598d0e4e112SXiaojian Du 	.set_power_profile_mode = vangogh_set_power_profile_mode,
1599307f049bSXiaojian Du 	.get_power_profile_mode = vangogh_get_power_profile_mode,
1600ae7b32e7SXiaojian Du 	.get_dpm_clock_table = vangogh_get_dpm_clock_table,
1601dd9e0b21SXiaojian Du 	.force_clk_levels = vangogh_force_clk_levels,
1602ea173d15SXiaojian Du 	.set_performance_level = vangogh_set_performance_level,
1603eefdf047SJinzhou Su 	.post_init = vangogh_post_smu_init,
1604*20e157c7SAlex Deucher 	.mode2_reset = vangogh_mode2_reset,
1605f46a221bSXiaojian Du };
1606f46a221bSXiaojian Du 
1607f46a221bSXiaojian Du void vangogh_set_ppt_funcs(struct smu_context *smu)
1608f46a221bSXiaojian Du {
1609f46a221bSXiaojian Du 	smu->ppt_funcs = &vangogh_ppt_funcs;
1610f46a221bSXiaojian Du 	smu->message_map = vangogh_message_map;
1611f46a221bSXiaojian Du 	smu->feature_map = vangogh_feature_mask_map;
1612f46a221bSXiaojian Du 	smu->table_map = vangogh_table_map;
1613f46a221bSXiaojian Du 	smu->is_apu = true;
1614f46a221bSXiaojian Du }
1615