Linux Audio

Check our new training course

Embedded Linux training

Mar 10-20, 2025, special US time zones
Register
Loading...
Note: File does not exist in v6.13.7.
   1/*
   2 * Copyright 2019 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#define SWSMU_CODE_LAYER_L2
  25
  26#include <linux/firmware.h>
  27#include "amdgpu.h"
  28#include "amdgpu_smu.h"
  29#include "atomfirmware.h"
  30#include "amdgpu_atomfirmware.h"
  31#include "amdgpu_atombios.h"
  32#include "smu_v11_0.h"
  33#include "smu11_driver_if_arcturus.h"
  34#include "soc15_common.h"
  35#include "atom.h"
  36#include "power_state.h"
  37#include "arcturus_ppt.h"
  38#include "smu_v11_0_pptable.h"
  39#include "arcturus_ppsmc.h"
  40#include "nbio/nbio_7_4_offset.h"
  41#include "nbio/nbio_7_4_sh_mask.h"
  42#include "thm/thm_11_0_2_offset.h"
  43#include "thm/thm_11_0_2_sh_mask.h"
  44#include "amdgpu_xgmi.h"
  45#include <linux/i2c.h>
  46#include <linux/pci.h>
  47#include "amdgpu_ras.h"
  48#include "smu_cmn.h"
  49
  50/*
  51 * DO NOT use these for err/warn/info/debug messages.
  52 * Use dev_err, dev_warn, dev_info and dev_dbg instead.
  53 * They are more MGPU friendly.
  54 */
  55#undef pr_err
  56#undef pr_warn
  57#undef pr_info
  58#undef pr_debug
  59
  60#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
  61
  62#define ARCTURUS_FEA_MAP(smu_feature, arcturus_feature) \
  63	[smu_feature] = {1, (arcturus_feature)}
  64
  65#define SMU_FEATURES_LOW_MASK        0x00000000FFFFFFFF
  66#define SMU_FEATURES_LOW_SHIFT       0
  67#define SMU_FEATURES_HIGH_MASK       0xFFFFFFFF00000000
  68#define SMU_FEATURES_HIGH_SHIFT      32
  69
  70#define SMC_DPM_FEATURE ( \
  71	FEATURE_DPM_PREFETCHER_MASK | \
  72	FEATURE_DPM_GFXCLK_MASK | \
  73	FEATURE_DPM_UCLK_MASK | \
  74	FEATURE_DPM_SOCCLK_MASK | \
  75	FEATURE_DPM_MP0CLK_MASK | \
  76	FEATURE_DPM_FCLK_MASK | \
  77	FEATURE_DPM_XGMI_MASK)
  78
  79/* possible frequency drift (1Mhz) */
  80#define EPSILON				1
  81
  82static const struct cmn2asic_msg_mapping arcturus_message_map[SMU_MSG_MAX_COUNT] = {
  83	MSG_MAP(TestMessage,			     PPSMC_MSG_TestMessage,			0),
  84	MSG_MAP(GetSmuVersion,			     PPSMC_MSG_GetSmuVersion,			1),
  85	MSG_MAP(GetDriverIfVersion,		     PPSMC_MSG_GetDriverIfVersion,		1),
  86	MSG_MAP(SetAllowedFeaturesMaskLow,	     PPSMC_MSG_SetAllowedFeaturesMaskLow,	0),
  87	MSG_MAP(SetAllowedFeaturesMaskHigh,	     PPSMC_MSG_SetAllowedFeaturesMaskHigh,	0),
  88	MSG_MAP(EnableAllSmuFeatures,		     PPSMC_MSG_EnableAllSmuFeatures,		0),
  89	MSG_MAP(DisableAllSmuFeatures,		     PPSMC_MSG_DisableAllSmuFeatures,		0),
  90	MSG_MAP(EnableSmuFeaturesLow,		     PPSMC_MSG_EnableSmuFeaturesLow,		1),
  91	MSG_MAP(EnableSmuFeaturesHigh,		     PPSMC_MSG_EnableSmuFeaturesHigh,		1),
  92	MSG_MAP(DisableSmuFeaturesLow,		     PPSMC_MSG_DisableSmuFeaturesLow,		0),
  93	MSG_MAP(DisableSmuFeaturesHigh,		     PPSMC_MSG_DisableSmuFeaturesHigh,		0),
  94	MSG_MAP(GetEnabledSmuFeaturesLow,	     PPSMC_MSG_GetEnabledSmuFeaturesLow,	0),
  95	MSG_MAP(GetEnabledSmuFeaturesHigh,	     PPSMC_MSG_GetEnabledSmuFeaturesHigh,	0),
  96	MSG_MAP(SetDriverDramAddrHigh,		     PPSMC_MSG_SetDriverDramAddrHigh,		1),
  97	MSG_MAP(SetDriverDramAddrLow,		     PPSMC_MSG_SetDriverDramAddrLow,		1),
  98	MSG_MAP(SetToolsDramAddrHigh,		     PPSMC_MSG_SetToolsDramAddrHigh,		0),
  99	MSG_MAP(SetToolsDramAddrLow,		     PPSMC_MSG_SetToolsDramAddrLow,		0),
 100	MSG_MAP(TransferTableSmu2Dram,		     PPSMC_MSG_TransferTableSmu2Dram,		1),
 101	MSG_MAP(TransferTableDram2Smu,		     PPSMC_MSG_TransferTableDram2Smu,		0),
 102	MSG_MAP(UseDefaultPPTable,		     PPSMC_MSG_UseDefaultPPTable,		0),
 103	MSG_MAP(UseBackupPPTable,		     PPSMC_MSG_UseBackupPPTable,		0),
 104	MSG_MAP(SetSystemVirtualDramAddrHigh,	     PPSMC_MSG_SetSystemVirtualDramAddrHigh,	0),
 105	MSG_MAP(SetSystemVirtualDramAddrLow,	     PPSMC_MSG_SetSystemVirtualDramAddrLow,	0),
 106	MSG_MAP(EnterBaco,			     PPSMC_MSG_EnterBaco,			0),
 107	MSG_MAP(ExitBaco,			     PPSMC_MSG_ExitBaco,			0),
 108	MSG_MAP(ArmD3,				     PPSMC_MSG_ArmD3,				0),
 109	MSG_MAP(SetSoftMinByFreq,		     PPSMC_MSG_SetSoftMinByFreq,		0),
 110	MSG_MAP(SetSoftMaxByFreq,		     PPSMC_MSG_SetSoftMaxByFreq,		0),
 111	MSG_MAP(SetHardMinByFreq,		     PPSMC_MSG_SetHardMinByFreq,		0),
 112	MSG_MAP(SetHardMaxByFreq,		     PPSMC_MSG_SetHardMaxByFreq,		0),
 113	MSG_MAP(GetMinDpmFreq,			     PPSMC_MSG_GetMinDpmFreq,			0),
 114	MSG_MAP(GetMaxDpmFreq,			     PPSMC_MSG_GetMaxDpmFreq,			0),
 115	MSG_MAP(GetDpmFreqByIndex,		     PPSMC_MSG_GetDpmFreqByIndex,		1),
 116	MSG_MAP(SetWorkloadMask,		     PPSMC_MSG_SetWorkloadMask,			1),
 117	MSG_MAP(SetDfSwitchType,		     PPSMC_MSG_SetDfSwitchType,			0),
 118	MSG_MAP(GetVoltageByDpm,		     PPSMC_MSG_GetVoltageByDpm,			0),
 119	MSG_MAP(GetVoltageByDpmOverdrive,	     PPSMC_MSG_GetVoltageByDpmOverdrive,	0),
 120	MSG_MAP(SetPptLimit,			     PPSMC_MSG_SetPptLimit,			0),
 121	MSG_MAP(GetPptLimit,			     PPSMC_MSG_GetPptLimit,			1),
 122	MSG_MAP(PowerUpVcn0,			     PPSMC_MSG_PowerUpVcn0,			0),
 123	MSG_MAP(PowerDownVcn0,			     PPSMC_MSG_PowerDownVcn0,			0),
 124	MSG_MAP(PowerUpVcn1,			     PPSMC_MSG_PowerUpVcn1,			0),
 125	MSG_MAP(PowerDownVcn1,			     PPSMC_MSG_PowerDownVcn1,			0),
 126	MSG_MAP(PrepareMp1ForUnload,		     PPSMC_MSG_PrepareMp1ForUnload,		0),
 127	MSG_MAP(PrepareMp1ForReset,		     PPSMC_MSG_PrepareMp1ForReset,		0),
 128	MSG_MAP(PrepareMp1ForShutdown,		     PPSMC_MSG_PrepareMp1ForShutdown,		0),
 129	MSG_MAP(SoftReset,			     PPSMC_MSG_SoftReset,			0),
 130	MSG_MAP(RunAfllBtc,			     PPSMC_MSG_RunAfllBtc,			0),
 131	MSG_MAP(RunDcBtc,			     PPSMC_MSG_RunDcBtc,			0),
 132	MSG_MAP(DramLogSetDramAddrHigh,		     PPSMC_MSG_DramLogSetDramAddrHigh,		0),
 133	MSG_MAP(DramLogSetDramAddrLow,		     PPSMC_MSG_DramLogSetDramAddrLow,		0),
 134	MSG_MAP(DramLogSetDramSize,		     PPSMC_MSG_DramLogSetDramSize,		0),
 135	MSG_MAP(GetDebugData,			     PPSMC_MSG_GetDebugData,			0),
 136	MSG_MAP(WaflTest,			     PPSMC_MSG_WaflTest,			0),
 137	MSG_MAP(SetXgmiMode,			     PPSMC_MSG_SetXgmiMode,			0),
 138	MSG_MAP(SetMemoryChannelEnable,		     PPSMC_MSG_SetMemoryChannelEnable,		0),
 139	MSG_MAP(DFCstateControl,		     PPSMC_MSG_DFCstateControl,			0),
 140	MSG_MAP(GmiPwrDnControl,		     PPSMC_MSG_GmiPwrDnControl,			0),
 141	MSG_MAP(ReadSerialNumTop32,		     PPSMC_MSG_ReadSerialNumTop32,		1),
 142	MSG_MAP(ReadSerialNumBottom32,		     PPSMC_MSG_ReadSerialNumBottom32,		1),
 143};
 144
 145static const struct cmn2asic_mapping arcturus_clk_map[SMU_CLK_COUNT] = {
 146	CLK_MAP(GFXCLK, PPCLK_GFXCLK),
 147	CLK_MAP(SCLK,	PPCLK_GFXCLK),
 148	CLK_MAP(SOCCLK, PPCLK_SOCCLK),
 149	CLK_MAP(FCLK, PPCLK_FCLK),
 150	CLK_MAP(UCLK, PPCLK_UCLK),
 151	CLK_MAP(MCLK, PPCLK_UCLK),
 152	CLK_MAP(DCLK, PPCLK_DCLK),
 153	CLK_MAP(VCLK, PPCLK_VCLK),
 154};
 155
 156static const struct cmn2asic_mapping arcturus_feature_mask_map[SMU_FEATURE_COUNT] = {
 157	FEA_MAP(DPM_PREFETCHER),
 158	FEA_MAP(DPM_GFXCLK),
 159	FEA_MAP(DPM_UCLK),
 160	FEA_MAP(DPM_SOCCLK),
 161	FEA_MAP(DPM_FCLK),
 162	FEA_MAP(DPM_MP0CLK),
 163	ARCTURUS_FEA_MAP(SMU_FEATURE_XGMI_BIT, FEATURE_DPM_XGMI_BIT),
 164	FEA_MAP(DS_GFXCLK),
 165	FEA_MAP(DS_SOCCLK),
 166	FEA_MAP(DS_LCLK),
 167	FEA_MAP(DS_FCLK),
 168	FEA_MAP(DS_UCLK),
 169	FEA_MAP(GFX_ULV),
 170	ARCTURUS_FEA_MAP(SMU_FEATURE_VCN_PG_BIT, FEATURE_DPM_VCN_BIT),
 171	FEA_MAP(RSMU_SMN_CG),
 172	FEA_MAP(WAFL_CG),
 173	FEA_MAP(PPT),
 174	FEA_MAP(TDC),
 175	FEA_MAP(APCC_PLUS),
 176	FEA_MAP(VR0HOT),
 177	FEA_MAP(VR1HOT),
 178	FEA_MAP(FW_CTF),
 179	FEA_MAP(FAN_CONTROL),
 180	FEA_MAP(THERMAL),
 181	FEA_MAP(OUT_OF_BAND_MONITOR),
 182	FEA_MAP(TEMP_DEPENDENT_VMIN),
 183};
 184
 185static const struct cmn2asic_mapping arcturus_table_map[SMU_TABLE_COUNT] = {
 186	TAB_MAP(PPTABLE),
 187	TAB_MAP(AVFS),
 188	TAB_MAP(AVFS_PSM_DEBUG),
 189	TAB_MAP(AVFS_FUSE_OVERRIDE),
 190	TAB_MAP(PMSTATUSLOG),
 191	TAB_MAP(SMU_METRICS),
 192	TAB_MAP(DRIVER_SMU_CONFIG),
 193	TAB_MAP(OVERDRIVE),
 194	TAB_MAP(I2C_COMMANDS),
 195	TAB_MAP(ACTIVITY_MONITOR_COEFF),
 196};
 197
 198static const struct cmn2asic_mapping arcturus_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
 199	PWR_MAP(AC),
 200	PWR_MAP(DC),
 201};
 202
 203static const struct cmn2asic_mapping arcturus_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
 204	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT,	WORKLOAD_PPLIB_DEFAULT_BIT),
 205	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING,		WORKLOAD_PPLIB_POWER_SAVING_BIT),
 206	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,		WORKLOAD_PPLIB_VIDEO_BIT),
 207	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,		WORKLOAD_PPLIB_COMPUTE_BIT),
 208	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,		WORKLOAD_PPLIB_CUSTOM_BIT),
 209};
 210
 211static int arcturus_tables_init(struct smu_context *smu)
 212{
 213	struct smu_table_context *smu_table = &smu->smu_table;
 214	struct smu_table *tables = smu_table->tables;
 215
 216	SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
 217		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 218
 219	SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE,
 220		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 221
 222	SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
 223		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 224
 225	SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
 226			       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 227
 228	SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF,
 229		       sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE,
 230		       AMDGPU_GEM_DOMAIN_VRAM);
 231
 232	smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
 233	if (!smu_table->metrics_table)
 234		return -ENOMEM;
 235	smu_table->metrics_time = 0;
 236
 237	return 0;
 238}
 239
 240static int arcturus_allocate_dpm_context(struct smu_context *smu)
 241{
 242	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
 243
 244	smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context),
 245				       GFP_KERNEL);
 246	if (!smu_dpm->dpm_context)
 247		return -ENOMEM;
 248	smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context);
 249
 250	smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state),
 251				       GFP_KERNEL);
 252	if (!smu_dpm->dpm_current_power_state)
 253		return -ENOMEM;
 254
 255	smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state),
 256				       GFP_KERNEL);
 257	if (!smu_dpm->dpm_request_power_state)
 258		return -ENOMEM;
 259
 260	return 0;
 261}
 262
 263static int arcturus_init_smc_tables(struct smu_context *smu)
 264{
 265	int ret = 0;
 266
 267	ret = arcturus_tables_init(smu);
 268	if (ret)
 269		return ret;
 270
 271	ret = arcturus_allocate_dpm_context(smu);
 272	if (ret)
 273		return ret;
 274
 275	return smu_v11_0_init_smc_tables(smu);
 276}
 277
 278static int
 279arcturus_get_allowed_feature_mask(struct smu_context *smu,
 280				  uint32_t *feature_mask, uint32_t num)
 281{
 282	if (num > 2)
 283		return -EINVAL;
 284
 285	/* pptable will handle the features to enable */
 286	memset(feature_mask, 0xFF, sizeof(uint32_t) * num);
 287
 288	return 0;
 289}
 290
 291static int arcturus_set_default_dpm_table(struct smu_context *smu)
 292{
 293	struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
 294	PPTable_t *driver_ppt = smu->smu_table.driver_pptable;
 295	struct smu_11_0_dpm_table *dpm_table = NULL;
 296	int ret = 0;
 297
 298	/* socclk dpm table setup */
 299	dpm_table = &dpm_context->dpm_tables.soc_table;
 300	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
 301		ret = smu_v11_0_set_single_dpm_table(smu,
 302						     SMU_SOCCLK,
 303						     dpm_table);
 304		if (ret)
 305			return ret;
 306		dpm_table->is_fine_grained =
 307			!driver_ppt->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete;
 308	} else {
 309		dpm_table->count = 1;
 310		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
 311		dpm_table->dpm_levels[0].enabled = true;
 312		dpm_table->min = dpm_table->dpm_levels[0].value;
 313		dpm_table->max = dpm_table->dpm_levels[0].value;
 314	}
 315
 316	/* gfxclk dpm table setup */
 317	dpm_table = &dpm_context->dpm_tables.gfx_table;
 318	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
 319		ret = smu_v11_0_set_single_dpm_table(smu,
 320						     SMU_GFXCLK,
 321						     dpm_table);
 322		if (ret)
 323			return ret;
 324		dpm_table->is_fine_grained =
 325			!driver_ppt->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete;
 326	} else {
 327		dpm_table->count = 1;
 328		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
 329		dpm_table->dpm_levels[0].enabled = true;
 330		dpm_table->min = dpm_table->dpm_levels[0].value;
 331		dpm_table->max = dpm_table->dpm_levels[0].value;
 332	}
 333
 334	/* memclk dpm table setup */
 335	dpm_table = &dpm_context->dpm_tables.uclk_table;
 336	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
 337		ret = smu_v11_0_set_single_dpm_table(smu,
 338						     SMU_UCLK,
 339						     dpm_table);
 340		if (ret)
 341			return ret;
 342		dpm_table->is_fine_grained =
 343			!driver_ppt->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete;
 344	} else {
 345		dpm_table->count = 1;
 346		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
 347		dpm_table->dpm_levels[0].enabled = true;
 348		dpm_table->min = dpm_table->dpm_levels[0].value;
 349		dpm_table->max = dpm_table->dpm_levels[0].value;
 350	}
 351
 352	/* fclk dpm table setup */
 353	dpm_table = &dpm_context->dpm_tables.fclk_table;
 354	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
 355		ret = smu_v11_0_set_single_dpm_table(smu,
 356						     SMU_FCLK,
 357						     dpm_table);
 358		if (ret)
 359			return ret;
 360		dpm_table->is_fine_grained =
 361			!driver_ppt->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete;
 362	} else {
 363		dpm_table->count = 1;
 364		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.fclk / 100;
 365		dpm_table->dpm_levels[0].enabled = true;
 366		dpm_table->min = dpm_table->dpm_levels[0].value;
 367		dpm_table->max = dpm_table->dpm_levels[0].value;
 368	}
 369
 370	return 0;
 371}
 372
 373static int arcturus_check_powerplay_table(struct smu_context *smu)
 374{
 375	struct smu_table_context *table_context = &smu->smu_table;
 376	struct smu_11_0_powerplay_table *powerplay_table =
 377		table_context->power_play_table;
 378	struct smu_baco_context *smu_baco = &smu->smu_baco;
 379
 380	mutex_lock(&smu_baco->mutex);
 381	if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_BACO ||
 382	    powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_MACO)
 383		smu_baco->platform_support = true;
 384	mutex_unlock(&smu_baco->mutex);
 385
 386	table_context->thermal_controller_type =
 387		powerplay_table->thermal_controller_type;
 388
 389	return 0;
 390}
 391
 392static int arcturus_store_powerplay_table(struct smu_context *smu)
 393{
 394	struct smu_table_context *table_context = &smu->smu_table;
 395	struct smu_11_0_powerplay_table *powerplay_table =
 396		table_context->power_play_table;
 397
 398	memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
 399	       sizeof(PPTable_t));
 400
 401	return 0;
 402}
 403
 404static int arcturus_append_powerplay_table(struct smu_context *smu)
 405{
 406	struct smu_table_context *table_context = &smu->smu_table;
 407	PPTable_t *smc_pptable = table_context->driver_pptable;
 408	struct atom_smc_dpm_info_v4_6 *smc_dpm_table;
 409	int index, ret;
 410
 411	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 412					   smc_dpm_info);
 413
 414	ret = amdgpu_atombios_get_data_table(smu->adev, index, NULL, NULL, NULL,
 415				      (uint8_t **)&smc_dpm_table);
 416	if (ret)
 417		return ret;
 418
 419	dev_info(smu->adev->dev, "smc_dpm_info table revision(format.content): %d.%d\n",
 420			smc_dpm_table->table_header.format_revision,
 421			smc_dpm_table->table_header.content_revision);
 422
 423	if ((smc_dpm_table->table_header.format_revision == 4) &&
 424	    (smc_dpm_table->table_header.content_revision == 6))
 425		memcpy(&smc_pptable->MaxVoltageStepGfx,
 426		       &smc_dpm_table->maxvoltagestepgfx,
 427		       sizeof(*smc_dpm_table) - offsetof(struct atom_smc_dpm_info_v4_6, maxvoltagestepgfx));
 428
 429	return 0;
 430}
 431
 432static int arcturus_setup_pptable(struct smu_context *smu)
 433{
 434	int ret = 0;
 435
 436	ret = smu_v11_0_setup_pptable(smu);
 437	if (ret)
 438		return ret;
 439
 440	ret = arcturus_store_powerplay_table(smu);
 441	if (ret)
 442		return ret;
 443
 444	ret = arcturus_append_powerplay_table(smu);
 445	if (ret)
 446		return ret;
 447
 448	ret = arcturus_check_powerplay_table(smu);
 449	if (ret)
 450		return ret;
 451
 452	return ret;
 453}
 454
 455static int arcturus_run_btc(struct smu_context *smu)
 456{
 457	int ret = 0;
 458
 459	ret = smu_cmn_send_smc_msg(smu, SMU_MSG_RunAfllBtc, NULL);
 460	if (ret) {
 461		dev_err(smu->adev->dev, "RunAfllBtc failed!\n");
 462		return ret;
 463	}
 464
 465	return smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
 466}
 467
 468static int arcturus_populate_umd_state_clk(struct smu_context *smu)
 469{
 470	struct smu_11_0_dpm_context *dpm_context =
 471				smu->smu_dpm.dpm_context;
 472	struct smu_11_0_dpm_table *gfx_table =
 473				&dpm_context->dpm_tables.gfx_table;
 474	struct smu_11_0_dpm_table *mem_table =
 475				&dpm_context->dpm_tables.uclk_table;
 476	struct smu_11_0_dpm_table *soc_table =
 477				&dpm_context->dpm_tables.soc_table;
 478	struct smu_umd_pstate_table *pstate_table =
 479				&smu->pstate_table;
 480
 481	pstate_table->gfxclk_pstate.min = gfx_table->min;
 482	pstate_table->gfxclk_pstate.peak = gfx_table->max;
 483
 484	pstate_table->uclk_pstate.min = mem_table->min;
 485	pstate_table->uclk_pstate.peak = mem_table->max;
 486
 487	pstate_table->socclk_pstate.min = soc_table->min;
 488	pstate_table->socclk_pstate.peak = soc_table->max;
 489
 490	if (gfx_table->count > ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL &&
 491	    mem_table->count > ARCTURUS_UMD_PSTATE_MCLK_LEVEL &&
 492	    soc_table->count > ARCTURUS_UMD_PSTATE_SOCCLK_LEVEL) {
 493		pstate_table->gfxclk_pstate.standard =
 494			gfx_table->dpm_levels[ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL].value;
 495		pstate_table->uclk_pstate.standard =
 496			mem_table->dpm_levels[ARCTURUS_UMD_PSTATE_MCLK_LEVEL].value;
 497		pstate_table->socclk_pstate.standard =
 498			soc_table->dpm_levels[ARCTURUS_UMD_PSTATE_SOCCLK_LEVEL].value;
 499	} else {
 500		pstate_table->gfxclk_pstate.standard =
 501			pstate_table->gfxclk_pstate.min;
 502		pstate_table->uclk_pstate.standard =
 503			pstate_table->uclk_pstate.min;
 504		pstate_table->socclk_pstate.standard =
 505			pstate_table->socclk_pstate.min;
 506	}
 507
 508	return 0;
 509}
 510
 511static int arcturus_get_clk_table(struct smu_context *smu,
 512			struct pp_clock_levels_with_latency *clocks,
 513			struct smu_11_0_dpm_table *dpm_table)
 514{
 515	int i, count;
 516
 517	count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
 518	clocks->num_levels = count;
 519
 520	for (i = 0; i < count; i++) {
 521		clocks->data[i].clocks_in_khz =
 522			dpm_table->dpm_levels[i].value * 1000;
 523		clocks->data[i].latency_in_us = 0;
 524	}
 525
 526	return 0;
 527}
 528
 529static int arcturus_freqs_in_same_level(int32_t frequency1,
 530					int32_t frequency2)
 531{
 532	return (abs(frequency1 - frequency2) <= EPSILON);
 533}
 534
 535static int arcturus_get_smu_metrics_data(struct smu_context *smu,
 536					 MetricsMember_t member,
 537					 uint32_t *value)
 538{
 539	struct smu_table_context *smu_table= &smu->smu_table;
 540	SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
 541	int ret = 0;
 542
 543	mutex_lock(&smu->metrics_lock);
 544
 545	if (!smu_table->metrics_time ||
 546	     time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(1))) {
 547		ret = smu_cmn_update_table(smu,
 548				       SMU_TABLE_SMU_METRICS,
 549				       0,
 550				       smu_table->metrics_table,
 551				       false);
 552		if (ret) {
 553			dev_info(smu->adev->dev, "Failed to export SMU metrics table!\n");
 554			mutex_unlock(&smu->metrics_lock);
 555			return ret;
 556		}
 557		smu_table->metrics_time = jiffies;
 558	}
 559
 560	switch (member) {
 561	case METRICS_CURR_GFXCLK:
 562		*value = metrics->CurrClock[PPCLK_GFXCLK];
 563		break;
 564	case METRICS_CURR_SOCCLK:
 565		*value = metrics->CurrClock[PPCLK_SOCCLK];
 566		break;
 567	case METRICS_CURR_UCLK:
 568		*value = metrics->CurrClock[PPCLK_UCLK];
 569		break;
 570	case METRICS_CURR_VCLK:
 571		*value = metrics->CurrClock[PPCLK_VCLK];
 572		break;
 573	case METRICS_CURR_DCLK:
 574		*value = metrics->CurrClock[PPCLK_DCLK];
 575		break;
 576	case METRICS_CURR_FCLK:
 577		*value = metrics->CurrClock[PPCLK_FCLK];
 578		break;
 579	case METRICS_AVERAGE_GFXCLK:
 580		*value = metrics->AverageGfxclkFrequency;
 581		break;
 582	case METRICS_AVERAGE_SOCCLK:
 583		*value = metrics->AverageSocclkFrequency;
 584		break;
 585	case METRICS_AVERAGE_UCLK:
 586		*value = metrics->AverageUclkFrequency;
 587		break;
 588	case METRICS_AVERAGE_VCLK:
 589		*value = metrics->AverageVclkFrequency;
 590		break;
 591	case METRICS_AVERAGE_DCLK:
 592		*value = metrics->AverageDclkFrequency;
 593		break;
 594	case METRICS_AVERAGE_GFXACTIVITY:
 595		*value = metrics->AverageGfxActivity;
 596		break;
 597	case METRICS_AVERAGE_MEMACTIVITY:
 598		*value = metrics->AverageUclkActivity;
 599		break;
 600	case METRICS_AVERAGE_VCNACTIVITY:
 601		*value = metrics->VcnActivityPercentage;
 602		break;
 603	case METRICS_AVERAGE_SOCKETPOWER:
 604		*value = metrics->AverageSocketPower << 8;
 605		break;
 606	case METRICS_TEMPERATURE_EDGE:
 607		*value = metrics->TemperatureEdge *
 608			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 609		break;
 610	case METRICS_TEMPERATURE_HOTSPOT:
 611		*value = metrics->TemperatureHotspot *
 612			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 613		break;
 614	case METRICS_TEMPERATURE_MEM:
 615		*value = metrics->TemperatureHBM *
 616			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 617		break;
 618	case METRICS_TEMPERATURE_VRGFX:
 619		*value = metrics->TemperatureVrGfx *
 620			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 621		break;
 622	case METRICS_TEMPERATURE_VRSOC:
 623		*value = metrics->TemperatureVrSoc *
 624			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 625		break;
 626	case METRICS_TEMPERATURE_VRMEM:
 627		*value = metrics->TemperatureVrMem *
 628			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 629		break;
 630	case METRICS_THROTTLER_STATUS:
 631		*value = metrics->ThrottlerStatus;
 632		break;
 633	case METRICS_CURR_FANSPEED:
 634		*value = metrics->CurrFanSpeed;
 635		break;
 636	default:
 637		*value = UINT_MAX;
 638		break;
 639	}
 640
 641	mutex_unlock(&smu->metrics_lock);
 642
 643	return ret;
 644}
 645
 646static int arcturus_get_current_clk_freq_by_table(struct smu_context *smu,
 647				       enum smu_clk_type clk_type,
 648				       uint32_t *value)
 649{
 650	MetricsMember_t member_type;
 651	int clk_id = 0;
 652
 653	if (!value)
 654		return -EINVAL;
 655
 656	clk_id = smu_cmn_to_asic_specific_index(smu,
 657						CMN2ASIC_MAPPING_CLK,
 658						clk_type);
 659	if (clk_id < 0)
 660		return -EINVAL;
 661
 662	switch (clk_id) {
 663	case PPCLK_GFXCLK:
 664		/*
 665		 * CurrClock[clk_id] can provide accurate
 666		 *   output only when the dpm feature is enabled.
 667		 * We can use Average_* for dpm disabled case.
 668		 *   But this is available for gfxclk/uclk/socclk/vclk/dclk.
 669		 */
 670		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT))
 671			member_type = METRICS_CURR_GFXCLK;
 672		else
 673			member_type = METRICS_AVERAGE_GFXCLK;
 674		break;
 675	case PPCLK_UCLK:
 676		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT))
 677			member_type = METRICS_CURR_UCLK;
 678		else
 679			member_type = METRICS_AVERAGE_UCLK;
 680		break;
 681	case PPCLK_SOCCLK:
 682		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT))
 683			member_type = METRICS_CURR_SOCCLK;
 684		else
 685			member_type = METRICS_AVERAGE_SOCCLK;
 686		break;
 687	case PPCLK_VCLK:
 688		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT))
 689			member_type = METRICS_CURR_VCLK;
 690		else
 691			member_type = METRICS_AVERAGE_VCLK;
 692		break;
 693	case PPCLK_DCLK:
 694		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT))
 695			member_type = METRICS_CURR_DCLK;
 696		else
 697			member_type = METRICS_AVERAGE_DCLK;
 698		break;
 699	case PPCLK_FCLK:
 700		member_type = METRICS_CURR_FCLK;
 701		break;
 702	default:
 703		return -EINVAL;
 704	}
 705
 706	return arcturus_get_smu_metrics_data(smu,
 707					     member_type,
 708					     value);
 709}
 710
 711static int arcturus_print_clk_levels(struct smu_context *smu,
 712			enum smu_clk_type type, char *buf)
 713{
 714	int i, now, size = 0;
 715	int ret = 0;
 716	struct pp_clock_levels_with_latency clocks;
 717	struct smu_11_0_dpm_table *single_dpm_table;
 718	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
 719	struct smu_11_0_dpm_context *dpm_context = NULL;
 720
 721	if (amdgpu_ras_intr_triggered())
 722		return snprintf(buf, PAGE_SIZE, "unavailable\n");
 723
 724	dpm_context = smu_dpm->dpm_context;
 725
 726	switch (type) {
 727	case SMU_SCLK:
 728		ret = arcturus_get_current_clk_freq_by_table(smu, SMU_GFXCLK, &now);
 729		if (ret) {
 730			dev_err(smu->adev->dev, "Attempt to get current gfx clk Failed!");
 731			return ret;
 732		}
 733
 734		single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
 735		ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
 736		if (ret) {
 737			dev_err(smu->adev->dev, "Attempt to get gfx clk levels Failed!");
 738			return ret;
 739		}
 740
 741		/*
 742		 * For DPM disabled case, there will be only one clock level.
 743		 * And it's safe to assume that is always the current clock.
 744		 */
 745		for (i = 0; i < clocks.num_levels; i++)
 746			size += sprintf(buf + size, "%d: %uMhz %s\n", i,
 747					clocks.data[i].clocks_in_khz / 1000,
 748					(clocks.num_levels == 1) ? "*" :
 749					(arcturus_freqs_in_same_level(
 750					clocks.data[i].clocks_in_khz / 1000,
 751					now) ? "*" : ""));
 752		break;
 753
 754	case SMU_MCLK:
 755		ret = arcturus_get_current_clk_freq_by_table(smu, SMU_UCLK, &now);
 756		if (ret) {
 757			dev_err(smu->adev->dev, "Attempt to get current mclk Failed!");
 758			return ret;
 759		}
 760
 761		single_dpm_table = &(dpm_context->dpm_tables.uclk_table);
 762		ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
 763		if (ret) {
 764			dev_err(smu->adev->dev, "Attempt to get memory clk levels Failed!");
 765			return ret;
 766		}
 767
 768		for (i = 0; i < clocks.num_levels; i++)
 769			size += sprintf(buf + size, "%d: %uMhz %s\n",
 770				i, clocks.data[i].clocks_in_khz / 1000,
 771				(clocks.num_levels == 1) ? "*" :
 772				(arcturus_freqs_in_same_level(
 773				clocks.data[i].clocks_in_khz / 1000,
 774				now) ? "*" : ""));
 775		break;
 776
 777	case SMU_SOCCLK:
 778		ret = arcturus_get_current_clk_freq_by_table(smu, SMU_SOCCLK, &now);
 779		if (ret) {
 780			dev_err(smu->adev->dev, "Attempt to get current socclk Failed!");
 781			return ret;
 782		}
 783
 784		single_dpm_table = &(dpm_context->dpm_tables.soc_table);
 785		ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
 786		if (ret) {
 787			dev_err(smu->adev->dev, "Attempt to get socclk levels Failed!");
 788			return ret;
 789		}
 790
 791		for (i = 0; i < clocks.num_levels; i++)
 792			size += sprintf(buf + size, "%d: %uMhz %s\n",
 793				i, clocks.data[i].clocks_in_khz / 1000,
 794				(clocks.num_levels == 1) ? "*" :
 795				(arcturus_freqs_in_same_level(
 796				clocks.data[i].clocks_in_khz / 1000,
 797				now) ? "*" : ""));
 798		break;
 799
 800	case SMU_FCLK:
 801		ret = arcturus_get_current_clk_freq_by_table(smu, SMU_FCLK, &now);
 802		if (ret) {
 803			dev_err(smu->adev->dev, "Attempt to get current fclk Failed!");
 804			return ret;
 805		}
 806
 807		single_dpm_table = &(dpm_context->dpm_tables.fclk_table);
 808		ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
 809		if (ret) {
 810			dev_err(smu->adev->dev, "Attempt to get fclk levels Failed!");
 811			return ret;
 812		}
 813
 814		for (i = 0; i < single_dpm_table->count; i++)
 815			size += sprintf(buf + size, "%d: %uMhz %s\n",
 816				i, single_dpm_table->dpm_levels[i].value,
 817				(clocks.num_levels == 1) ? "*" :
 818				(arcturus_freqs_in_same_level(
 819				clocks.data[i].clocks_in_khz / 1000,
 820				now) ? "*" : ""));
 821		break;
 822
 823	default:
 824		break;
 825	}
 826
 827	return size;
 828}
 829
 830static int arcturus_upload_dpm_level(struct smu_context *smu,
 831				     bool max,
 832				     uint32_t feature_mask,
 833				     uint32_t level)
 834{
 835	struct smu_11_0_dpm_context *dpm_context =
 836			smu->smu_dpm.dpm_context;
 837	uint32_t freq;
 838	int ret = 0;
 839
 840	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT) &&
 841	    (feature_mask & FEATURE_DPM_GFXCLK_MASK)) {
 842		freq = dpm_context->dpm_tables.gfx_table.dpm_levels[level].value;
 843		ret = smu_cmn_send_smc_msg_with_param(smu,
 844			(max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
 845			(PPCLK_GFXCLK << 16) | (freq & 0xffff),
 846			NULL);
 847		if (ret) {
 848			dev_err(smu->adev->dev, "Failed to set soft %s gfxclk !\n",
 849						max ? "max" : "min");
 850			return ret;
 851		}
 852	}
 853
 854	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
 855	    (feature_mask & FEATURE_DPM_UCLK_MASK)) {
 856		freq = dpm_context->dpm_tables.uclk_table.dpm_levels[level].value;
 857		ret = smu_cmn_send_smc_msg_with_param(smu,
 858			(max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
 859			(PPCLK_UCLK << 16) | (freq & 0xffff),
 860			NULL);
 861		if (ret) {
 862			dev_err(smu->adev->dev, "Failed to set soft %s memclk !\n",
 863						max ? "max" : "min");
 864			return ret;
 865		}
 866	}
 867
 868	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT) &&
 869	    (feature_mask & FEATURE_DPM_SOCCLK_MASK)) {
 870		freq = dpm_context->dpm_tables.soc_table.dpm_levels[level].value;
 871		ret = smu_cmn_send_smc_msg_with_param(smu,
 872			(max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
 873			(PPCLK_SOCCLK << 16) | (freq & 0xffff),
 874			NULL);
 875		if (ret) {
 876			dev_err(smu->adev->dev, "Failed to set soft %s socclk !\n",
 877						max ? "max" : "min");
 878			return ret;
 879		}
 880	}
 881
 882	return ret;
 883}
 884
 885static int arcturus_force_clk_levels(struct smu_context *smu,
 886			enum smu_clk_type type, uint32_t mask)
 887{
 888	struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
 889	struct smu_11_0_dpm_table *single_dpm_table = NULL;
 890	uint32_t soft_min_level, soft_max_level;
 891	uint32_t smu_version;
 892	int ret = 0;
 893
 894	ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
 895	if (ret) {
 896		dev_err(smu->adev->dev, "Failed to get smu version!\n");
 897		return ret;
 898	}
 899
 900	if (smu_version >= 0x361200) {
 901		dev_err(smu->adev->dev, "Forcing clock level is not supported with "
 902		       "54.18 and onwards SMU firmwares\n");
 903		return -EOPNOTSUPP;
 904	}
 905
 906	soft_min_level = mask ? (ffs(mask) - 1) : 0;
 907	soft_max_level = mask ? (fls(mask) - 1) : 0;
 908
 909	switch (type) {
 910	case SMU_SCLK:
 911		single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
 912		if (soft_max_level >= single_dpm_table->count) {
 913			dev_err(smu->adev->dev, "Clock level specified %d is over max allowed %d\n",
 914					soft_max_level, single_dpm_table->count - 1);
 915			ret = -EINVAL;
 916			break;
 917		}
 918
 919		ret = arcturus_upload_dpm_level(smu,
 920						false,
 921						FEATURE_DPM_GFXCLK_MASK,
 922						soft_min_level);
 923		if (ret) {
 924			dev_err(smu->adev->dev, "Failed to upload boot level to lowest!\n");
 925			break;
 926		}
 927
 928		ret = arcturus_upload_dpm_level(smu,
 929						true,
 930						FEATURE_DPM_GFXCLK_MASK,
 931						soft_max_level);
 932		if (ret)
 933			dev_err(smu->adev->dev, "Failed to upload dpm max level to highest!\n");
 934
 935		break;
 936
 937	case SMU_MCLK:
 938	case SMU_SOCCLK:
 939	case SMU_FCLK:
 940		/*
 941		 * Should not arrive here since Arcturus does not
 942		 * support mclk/socclk/fclk softmin/softmax settings
 943		 */
 944		ret = -EINVAL;
 945		break;
 946
 947	default:
 948		break;
 949	}
 950
 951	return ret;
 952}
 953
 954static int arcturus_get_thermal_temperature_range(struct smu_context *smu,
 955						struct smu_temperature_range *range)
 956{
 957	struct smu_table_context *table_context = &smu->smu_table;
 958	struct smu_11_0_powerplay_table *powerplay_table =
 959				table_context->power_play_table;
 960	PPTable_t *pptable = smu->smu_table.driver_pptable;
 961
 962	if (!range)
 963		return -EINVAL;
 964
 965	memcpy(range, &smu11_thermal_policy[0], sizeof(struct smu_temperature_range));
 966
 967	range->max = pptable->TedgeLimit *
 968		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 969	range->edge_emergency_max = (pptable->TedgeLimit + CTF_OFFSET_EDGE) *
 970		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 971	range->hotspot_crit_max = pptable->ThotspotLimit *
 972		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 973	range->hotspot_emergency_max = (pptable->ThotspotLimit + CTF_OFFSET_HOTSPOT) *
 974		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 975	range->mem_crit_max = pptable->TmemLimit *
 976		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 977	range->mem_emergency_max = (pptable->TmemLimit + CTF_OFFSET_MEM)*
 978		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 979	range->software_shutdown_temp = powerplay_table->software_shutdown_temp;
 980
 981	return 0;
 982}
 983
 984static int arcturus_get_current_activity_percent(struct smu_context *smu,
 985						 enum amd_pp_sensors sensor,
 986						 uint32_t *value)
 987{
 988	int ret = 0;
 989
 990	if (!value)
 991		return -EINVAL;
 992
 993	switch (sensor) {
 994	case AMDGPU_PP_SENSOR_GPU_LOAD:
 995		ret = arcturus_get_smu_metrics_data(smu,
 996						    METRICS_AVERAGE_GFXACTIVITY,
 997						    value);
 998		break;
 999	case AMDGPU_PP_SENSOR_MEM_LOAD:
1000		ret = arcturus_get_smu_metrics_data(smu,
1001						    METRICS_AVERAGE_MEMACTIVITY,
1002						    value);
1003		break;
1004	default:
1005		dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n");
1006		return -EINVAL;
1007	}
1008
1009	return ret;
1010}
1011
1012static int arcturus_get_gpu_power(struct smu_context *smu, uint32_t *value)
1013{
1014	if (!value)
1015		return -EINVAL;
1016
1017	return arcturus_get_smu_metrics_data(smu,
1018					     METRICS_AVERAGE_SOCKETPOWER,
1019					     value);
1020}
1021
1022static int arcturus_thermal_get_temperature(struct smu_context *smu,
1023					    enum amd_pp_sensors sensor,
1024					    uint32_t *value)
1025{
1026	int ret = 0;
1027
1028	if (!value)
1029		return -EINVAL;
1030
1031	switch (sensor) {
1032	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1033		ret = arcturus_get_smu_metrics_data(smu,
1034						    METRICS_TEMPERATURE_HOTSPOT,
1035						    value);
1036		break;
1037	case AMDGPU_PP_SENSOR_EDGE_TEMP:
1038		ret = arcturus_get_smu_metrics_data(smu,
1039						    METRICS_TEMPERATURE_EDGE,
1040						    value);
1041		break;
1042	case AMDGPU_PP_SENSOR_MEM_TEMP:
1043		ret = arcturus_get_smu_metrics_data(smu,
1044						    METRICS_TEMPERATURE_MEM,
1045						    value);
1046		break;
1047	default:
1048		dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n");
1049		return -EINVAL;
1050	}
1051
1052	return ret;
1053}
1054
1055static int arcturus_read_sensor(struct smu_context *smu,
1056				enum amd_pp_sensors sensor,
1057				void *data, uint32_t *size)
1058{
1059	struct smu_table_context *table_context = &smu->smu_table;
1060	PPTable_t *pptable = table_context->driver_pptable;
1061	int ret = 0;
1062
1063	if (amdgpu_ras_intr_triggered())
1064		return 0;
1065
1066	if (!data || !size)
1067		return -EINVAL;
1068
1069	mutex_lock(&smu->sensor_lock);
1070	switch (sensor) {
1071	case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
1072		*(uint32_t *)data = pptable->FanMaximumRpm;
1073		*size = 4;
1074		break;
1075	case AMDGPU_PP_SENSOR_MEM_LOAD:
1076	case AMDGPU_PP_SENSOR_GPU_LOAD:
1077		ret = arcturus_get_current_activity_percent(smu,
1078							    sensor,
1079						(uint32_t *)data);
1080		*size = 4;
1081		break;
1082	case AMDGPU_PP_SENSOR_GPU_POWER:
1083		ret = arcturus_get_gpu_power(smu, (uint32_t *)data);
1084		*size = 4;
1085		break;
1086	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1087	case AMDGPU_PP_SENSOR_EDGE_TEMP:
1088	case AMDGPU_PP_SENSOR_MEM_TEMP:
1089		ret = arcturus_thermal_get_temperature(smu, sensor,
1090						(uint32_t *)data);
1091		*size = 4;
1092		break;
1093	case AMDGPU_PP_SENSOR_GFX_MCLK:
1094		ret = arcturus_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data);
1095		/* the output clock frequency in 10K unit */
1096		*(uint32_t *)data *= 100;
1097		*size = 4;
1098		break;
1099	case AMDGPU_PP_SENSOR_GFX_SCLK:
1100		ret = arcturus_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data);
1101		*(uint32_t *)data *= 100;
1102		*size = 4;
1103		break;
1104	case AMDGPU_PP_SENSOR_VDDGFX:
1105		ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data);
1106		*size = 4;
1107		break;
1108	default:
1109		ret = -EOPNOTSUPP;
1110		break;
1111	}
1112	mutex_unlock(&smu->sensor_lock);
1113
1114	return ret;
1115}
1116
1117static int arcturus_get_fan_speed_rpm(struct smu_context *smu,
1118				      uint32_t *speed)
1119{
1120	if (!speed)
1121		return -EINVAL;
1122
1123	return arcturus_get_smu_metrics_data(smu,
1124					     METRICS_CURR_FANSPEED,
1125					     speed);
1126}
1127
1128static int arcturus_get_fan_speed_percent(struct smu_context *smu,
1129					  uint32_t *speed)
1130{
1131	PPTable_t *pptable = smu->smu_table.driver_pptable;
1132	uint32_t percent, current_rpm;
1133	int ret = 0;
1134
1135	if (!speed)
1136		return -EINVAL;
1137
1138	ret = arcturus_get_fan_speed_rpm(smu, &current_rpm);
1139	if (ret)
1140		return ret;
1141
1142	percent = current_rpm * 100 / pptable->FanMaximumRpm;
1143	*speed = percent > 100 ? 100 : percent;
1144
1145	return ret;
1146}
1147
1148static int arcturus_get_power_limit(struct smu_context *smu)
1149{
1150	struct smu_11_0_powerplay_table *powerplay_table =
1151		(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
1152	PPTable_t *pptable = smu->smu_table.driver_pptable;
1153	uint32_t power_limit, od_percent;
1154
1155	if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
1156		/* the last hope to figure out the ppt limit */
1157		if (!pptable) {
1158			dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!");
1159			return -EINVAL;
1160		}
1161		power_limit =
1162			pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
1163	}
1164	smu->current_power_limit = power_limit;
1165
1166	if (smu->od_enabled) {
1167		od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
1168
1169		dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
1170
1171		power_limit *= (100 + od_percent);
1172		power_limit /= 100;
1173	}
1174	smu->max_power_limit = power_limit;
1175
1176	return 0;
1177}
1178
1179static int arcturus_get_power_profile_mode(struct smu_context *smu,
1180					   char *buf)
1181{
1182	DpmActivityMonitorCoeffInt_t activity_monitor;
1183	static const char *profile_name[] = {
1184					"BOOTUP_DEFAULT",
1185					"3D_FULL_SCREEN",
1186					"POWER_SAVING",
1187					"VIDEO",
1188					"VR",
1189					"COMPUTE",
1190					"CUSTOM"};
1191	static const char *title[] = {
1192			"PROFILE_INDEX(NAME)",
1193			"CLOCK_TYPE(NAME)",
1194			"FPS",
1195			"UseRlcBusy",
1196			"MinActiveFreqType",
1197			"MinActiveFreq",
1198			"BoosterFreqType",
1199			"BoosterFreq",
1200			"PD_Data_limit_c",
1201			"PD_Data_error_coeff",
1202			"PD_Data_error_rate_coeff"};
1203	uint32_t i, size = 0;
1204	int16_t workload_type = 0;
1205	int result = 0;
1206	uint32_t smu_version;
1207
1208	if (!buf)
1209		return -EINVAL;
1210
1211	result = smu_cmn_get_smc_version(smu, NULL, &smu_version);
1212	if (result)
1213		return result;
1214
1215	if (smu_version >= 0x360d00)
1216		size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n",
1217			title[0], title[1], title[2], title[3], title[4], title[5],
1218			title[6], title[7], title[8], title[9], title[10]);
1219	else
1220		size += sprintf(buf + size, "%16s\n",
1221			title[0]);
1222
1223	for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
1224		/*
1225		 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1226		 * Not all profile modes are supported on arcturus.
1227		 */
1228		workload_type = smu_cmn_to_asic_specific_index(smu,
1229							       CMN2ASIC_MAPPING_WORKLOAD,
1230							       i);
1231		if (workload_type < 0)
1232			continue;
1233
1234		if (smu_version >= 0x360d00) {
1235			result = smu_cmn_update_table(smu,
1236						  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1237						  workload_type,
1238						  (void *)(&activity_monitor),
1239						  false);
1240			if (result) {
1241				dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1242				return result;
1243			}
1244		}
1245
1246		size += sprintf(buf + size, "%2d %14s%s\n",
1247			i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
1248
1249		if (smu_version >= 0x360d00) {
1250			size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1251				" ",
1252				0,
1253				"GFXCLK",
1254				activity_monitor.Gfx_FPS,
1255				activity_monitor.Gfx_UseRlcBusy,
1256				activity_monitor.Gfx_MinActiveFreqType,
1257				activity_monitor.Gfx_MinActiveFreq,
1258				activity_monitor.Gfx_BoosterFreqType,
1259				activity_monitor.Gfx_BoosterFreq,
1260				activity_monitor.Gfx_PD_Data_limit_c,
1261				activity_monitor.Gfx_PD_Data_error_coeff,
1262				activity_monitor.Gfx_PD_Data_error_rate_coeff);
1263
1264			size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1265				" ",
1266				1,
1267				"UCLK",
1268				activity_monitor.Mem_FPS,
1269				activity_monitor.Mem_UseRlcBusy,
1270				activity_monitor.Mem_MinActiveFreqType,
1271				activity_monitor.Mem_MinActiveFreq,
1272				activity_monitor.Mem_BoosterFreqType,
1273				activity_monitor.Mem_BoosterFreq,
1274				activity_monitor.Mem_PD_Data_limit_c,
1275				activity_monitor.Mem_PD_Data_error_coeff,
1276				activity_monitor.Mem_PD_Data_error_rate_coeff);
1277		}
1278	}
1279
1280	return size;
1281}
1282
1283static int arcturus_set_power_profile_mode(struct smu_context *smu,
1284					   long *input,
1285					   uint32_t size)
1286{
1287	DpmActivityMonitorCoeffInt_t activity_monitor;
1288	int workload_type = 0;
1289	uint32_t profile_mode = input[size];
1290	int ret = 0;
1291	uint32_t smu_version;
1292
1293	if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
1294		dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);
1295		return -EINVAL;
1296	}
1297
1298	ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
1299	if (ret)
1300		return ret;
1301
1302	if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&
1303	     (smu_version >=0x360d00)) {
1304		ret = smu_cmn_update_table(smu,
1305				       SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1306				       WORKLOAD_PPLIB_CUSTOM_BIT,
1307				       (void *)(&activity_monitor),
1308				       false);
1309		if (ret) {
1310			dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1311			return ret;
1312		}
1313
1314		switch (input[0]) {
1315		case 0: /* Gfxclk */
1316			activity_monitor.Gfx_FPS = input[1];
1317			activity_monitor.Gfx_UseRlcBusy = input[2];
1318			activity_monitor.Gfx_MinActiveFreqType = input[3];
1319			activity_monitor.Gfx_MinActiveFreq = input[4];
1320			activity_monitor.Gfx_BoosterFreqType = input[5];
1321			activity_monitor.Gfx_BoosterFreq = input[6];
1322			activity_monitor.Gfx_PD_Data_limit_c = input[7];
1323			activity_monitor.Gfx_PD_Data_error_coeff = input[8];
1324			activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9];
1325			break;
1326		case 1: /* Uclk */
1327			activity_monitor.Mem_FPS = input[1];
1328			activity_monitor.Mem_UseRlcBusy = input[2];
1329			activity_monitor.Mem_MinActiveFreqType = input[3];
1330			activity_monitor.Mem_MinActiveFreq = input[4];
1331			activity_monitor.Mem_BoosterFreqType = input[5];
1332			activity_monitor.Mem_BoosterFreq = input[6];
1333			activity_monitor.Mem_PD_Data_limit_c = input[7];
1334			activity_monitor.Mem_PD_Data_error_coeff = input[8];
1335			activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
1336			break;
1337		}
1338
1339		ret = smu_cmn_update_table(smu,
1340				       SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1341				       WORKLOAD_PPLIB_CUSTOM_BIT,
1342				       (void *)(&activity_monitor),
1343				       true);
1344		if (ret) {
1345			dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
1346			return ret;
1347		}
1348	}
1349
1350	/*
1351	 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1352	 * Not all profile modes are supported on arcturus.
1353	 */
1354	workload_type = smu_cmn_to_asic_specific_index(smu,
1355						       CMN2ASIC_MAPPING_WORKLOAD,
1356						       profile_mode);
1357	if (workload_type < 0) {
1358		dev_err(smu->adev->dev, "Unsupported power profile mode %d on arcturus\n", profile_mode);
1359		return -EINVAL;
1360	}
1361
1362	ret = smu_cmn_send_smc_msg_with_param(smu,
1363					  SMU_MSG_SetWorkloadMask,
1364					  1 << workload_type,
1365					  NULL);
1366	if (ret) {
1367		dev_err(smu->adev->dev, "Fail to set workload type %d\n", workload_type);
1368		return ret;
1369	}
1370
1371	smu->power_profile_mode = profile_mode;
1372
1373	return 0;
1374}
1375
1376static int arcturus_set_performance_level(struct smu_context *smu,
1377					  enum amd_dpm_forced_level level)
1378{
1379	uint32_t smu_version;
1380	int ret;
1381
1382	ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
1383	if (ret) {
1384		dev_err(smu->adev->dev, "Failed to get smu version!\n");
1385		return ret;
1386	}
1387
1388	switch (level) {
1389	case AMD_DPM_FORCED_LEVEL_HIGH:
1390	case AMD_DPM_FORCED_LEVEL_LOW:
1391	case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1392	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1393	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1394	case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1395		if (smu_version >= 0x361200) {
1396			dev_err(smu->adev->dev, "Forcing clock level is not supported with "
1397			       "54.18 and onwards SMU firmwares\n");
1398			return -EOPNOTSUPP;
1399		}
1400		break;
1401	default:
1402		break;
1403	}
1404
1405	return smu_v11_0_set_performance_level(smu, level);
1406}
1407
1408static void arcturus_dump_pptable(struct smu_context *smu)
1409{
1410	struct smu_table_context *table_context = &smu->smu_table;
1411	PPTable_t *pptable = table_context->driver_pptable;
1412	int i;
1413
1414	dev_info(smu->adev->dev, "Dumped PPTable:\n");
1415
1416	dev_info(smu->adev->dev, "Version = 0x%08x\n", pptable->Version);
1417
1418	dev_info(smu->adev->dev, "FeaturesToRun[0] = 0x%08x\n", pptable->FeaturesToRun[0]);
1419	dev_info(smu->adev->dev, "FeaturesToRun[1] = 0x%08x\n", pptable->FeaturesToRun[1]);
1420
1421	for (i = 0; i < PPT_THROTTLER_COUNT; i++) {
1422		dev_info(smu->adev->dev, "SocketPowerLimitAc[%d] = %d\n", i, pptable->SocketPowerLimitAc[i]);
1423		dev_info(smu->adev->dev, "SocketPowerLimitAcTau[%d] = %d\n", i, pptable->SocketPowerLimitAcTau[i]);
1424	}
1425
1426	dev_info(smu->adev->dev, "TdcLimitSoc = %d\n", pptable->TdcLimitSoc);
1427	dev_info(smu->adev->dev, "TdcLimitSocTau = %d\n", pptable->TdcLimitSocTau);
1428	dev_info(smu->adev->dev, "TdcLimitGfx = %d\n", pptable->TdcLimitGfx);
1429	dev_info(smu->adev->dev, "TdcLimitGfxTau = %d\n", pptable->TdcLimitGfxTau);
1430
1431	dev_info(smu->adev->dev, "TedgeLimit = %d\n", pptable->TedgeLimit);
1432	dev_info(smu->adev->dev, "ThotspotLimit = %d\n", pptable->ThotspotLimit);
1433	dev_info(smu->adev->dev, "TmemLimit = %d\n", pptable->TmemLimit);
1434	dev_info(smu->adev->dev, "Tvr_gfxLimit = %d\n", pptable->Tvr_gfxLimit);
1435	dev_info(smu->adev->dev, "Tvr_memLimit = %d\n", pptable->Tvr_memLimit);
1436	dev_info(smu->adev->dev, "Tvr_socLimit = %d\n", pptable->Tvr_socLimit);
1437	dev_info(smu->adev->dev, "FitLimit = %d\n", pptable->FitLimit);
1438
1439	dev_info(smu->adev->dev, "PpmPowerLimit = %d\n", pptable->PpmPowerLimit);
1440	dev_info(smu->adev->dev, "PpmTemperatureThreshold = %d\n", pptable->PpmTemperatureThreshold);
1441
1442	dev_info(smu->adev->dev, "ThrottlerControlMask = %d\n", pptable->ThrottlerControlMask);
1443
1444	dev_info(smu->adev->dev, "UlvVoltageOffsetGfx = %d\n", pptable->UlvVoltageOffsetGfx);
1445	dev_info(smu->adev->dev, "UlvPadding = 0x%08x\n", pptable->UlvPadding);
1446
1447	dev_info(smu->adev->dev, "UlvGfxclkBypass = %d\n", pptable->UlvGfxclkBypass);
1448	dev_info(smu->adev->dev, "Padding234[0] = 0x%02x\n", pptable->Padding234[0]);
1449	dev_info(smu->adev->dev, "Padding234[1] = 0x%02x\n", pptable->Padding234[1]);
1450	dev_info(smu->adev->dev, "Padding234[2] = 0x%02x\n", pptable->Padding234[2]);
1451
1452	dev_info(smu->adev->dev, "MinVoltageGfx = %d\n", pptable->MinVoltageGfx);
1453	dev_info(smu->adev->dev, "MinVoltageSoc = %d\n", pptable->MinVoltageSoc);
1454	dev_info(smu->adev->dev, "MaxVoltageGfx = %d\n", pptable->MaxVoltageGfx);
1455	dev_info(smu->adev->dev, "MaxVoltageSoc = %d\n", pptable->MaxVoltageSoc);
1456
1457	dev_info(smu->adev->dev, "LoadLineResistanceGfx = %d\n", pptable->LoadLineResistanceGfx);
1458	dev_info(smu->adev->dev, "LoadLineResistanceSoc = %d\n", pptable->LoadLineResistanceSoc);
1459
1460	dev_info(smu->adev->dev, "[PPCLK_GFXCLK]\n"
1461			"  .VoltageMode          = 0x%02x\n"
1462			"  .SnapToDiscrete       = 0x%02x\n"
1463			"  .NumDiscreteLevels    = 0x%02x\n"
1464			"  .padding              = 0x%02x\n"
1465			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1466			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1467			"  .SsFmin               = 0x%04x\n"
1468			"  .Padding_16           = 0x%04x\n",
1469			pptable->DpmDescriptor[PPCLK_GFXCLK].VoltageMode,
1470			pptable->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete,
1471			pptable->DpmDescriptor[PPCLK_GFXCLK].NumDiscreteLevels,
1472			pptable->DpmDescriptor[PPCLK_GFXCLK].padding,
1473			pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.m,
1474			pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.b,
1475			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.a,
1476			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.b,
1477			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.c,
1478			pptable->DpmDescriptor[PPCLK_GFXCLK].SsFmin,
1479			pptable->DpmDescriptor[PPCLK_GFXCLK].Padding16);
1480
1481	dev_info(smu->adev->dev, "[PPCLK_VCLK]\n"
1482			"  .VoltageMode          = 0x%02x\n"
1483			"  .SnapToDiscrete       = 0x%02x\n"
1484			"  .NumDiscreteLevels    = 0x%02x\n"
1485			"  .padding              = 0x%02x\n"
1486			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1487			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1488			"  .SsFmin               = 0x%04x\n"
1489			"  .Padding_16           = 0x%04x\n",
1490			pptable->DpmDescriptor[PPCLK_VCLK].VoltageMode,
1491			pptable->DpmDescriptor[PPCLK_VCLK].SnapToDiscrete,
1492			pptable->DpmDescriptor[PPCLK_VCLK].NumDiscreteLevels,
1493			pptable->DpmDescriptor[PPCLK_VCLK].padding,
1494			pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.m,
1495			pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.b,
1496			pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.a,
1497			pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.b,
1498			pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.c,
1499			pptable->DpmDescriptor[PPCLK_VCLK].SsFmin,
1500			pptable->DpmDescriptor[PPCLK_VCLK].Padding16);
1501
1502	dev_info(smu->adev->dev, "[PPCLK_DCLK]\n"
1503			"  .VoltageMode          = 0x%02x\n"
1504			"  .SnapToDiscrete       = 0x%02x\n"
1505			"  .NumDiscreteLevels    = 0x%02x\n"
1506			"  .padding              = 0x%02x\n"
1507			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1508			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1509			"  .SsFmin               = 0x%04x\n"
1510			"  .Padding_16           = 0x%04x\n",
1511			pptable->DpmDescriptor[PPCLK_DCLK].VoltageMode,
1512			pptable->DpmDescriptor[PPCLK_DCLK].SnapToDiscrete,
1513			pptable->DpmDescriptor[PPCLK_DCLK].NumDiscreteLevels,
1514			pptable->DpmDescriptor[PPCLK_DCLK].padding,
1515			pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.m,
1516			pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.b,
1517			pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.a,
1518			pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.b,
1519			pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.c,
1520			pptable->DpmDescriptor[PPCLK_DCLK].SsFmin,
1521			pptable->DpmDescriptor[PPCLK_DCLK].Padding16);
1522
1523	dev_info(smu->adev->dev, "[PPCLK_SOCCLK]\n"
1524			"  .VoltageMode          = 0x%02x\n"
1525			"  .SnapToDiscrete       = 0x%02x\n"
1526			"  .NumDiscreteLevels    = 0x%02x\n"
1527			"  .padding              = 0x%02x\n"
1528			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1529			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1530			"  .SsFmin               = 0x%04x\n"
1531			"  .Padding_16           = 0x%04x\n",
1532			pptable->DpmDescriptor[PPCLK_SOCCLK].VoltageMode,
1533			pptable->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete,
1534			pptable->DpmDescriptor[PPCLK_SOCCLK].NumDiscreteLevels,
1535			pptable->DpmDescriptor[PPCLK_SOCCLK].padding,
1536			pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.m,
1537			pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.b,
1538			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.a,
1539			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.b,
1540			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.c,
1541			pptable->DpmDescriptor[PPCLK_SOCCLK].SsFmin,
1542			pptable->DpmDescriptor[PPCLK_SOCCLK].Padding16);
1543
1544	dev_info(smu->adev->dev, "[PPCLK_UCLK]\n"
1545			"  .VoltageMode          = 0x%02x\n"
1546			"  .SnapToDiscrete       = 0x%02x\n"
1547			"  .NumDiscreteLevels    = 0x%02x\n"
1548			"  .padding              = 0x%02x\n"
1549			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1550			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1551			"  .SsFmin               = 0x%04x\n"
1552			"  .Padding_16           = 0x%04x\n",
1553			pptable->DpmDescriptor[PPCLK_UCLK].VoltageMode,
1554			pptable->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete,
1555			pptable->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels,
1556			pptable->DpmDescriptor[PPCLK_UCLK].padding,
1557			pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.m,
1558			pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.b,
1559			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.a,
1560			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.b,
1561			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.c,
1562			pptable->DpmDescriptor[PPCLK_UCLK].SsFmin,
1563			pptable->DpmDescriptor[PPCLK_UCLK].Padding16);
1564
1565	dev_info(smu->adev->dev, "[PPCLK_FCLK]\n"
1566			"  .VoltageMode          = 0x%02x\n"
1567			"  .SnapToDiscrete       = 0x%02x\n"
1568			"  .NumDiscreteLevels    = 0x%02x\n"
1569			"  .padding              = 0x%02x\n"
1570			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1571			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1572			"  .SsFmin               = 0x%04x\n"
1573			"  .Padding_16           = 0x%04x\n",
1574			pptable->DpmDescriptor[PPCLK_FCLK].VoltageMode,
1575			pptable->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete,
1576			pptable->DpmDescriptor[PPCLK_FCLK].NumDiscreteLevels,
1577			pptable->DpmDescriptor[PPCLK_FCLK].padding,
1578			pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.m,
1579			pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.b,
1580			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.a,
1581			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.b,
1582			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.c,
1583			pptable->DpmDescriptor[PPCLK_FCLK].SsFmin,
1584			pptable->DpmDescriptor[PPCLK_FCLK].Padding16);
1585
1586
1587	dev_info(smu->adev->dev, "FreqTableGfx\n");
1588	for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++)
1589		dev_info(smu->adev->dev, "  .[%02d] = %d\n", i, pptable->FreqTableGfx[i]);
1590
1591	dev_info(smu->adev->dev, "FreqTableVclk\n");
1592	for (i = 0; i < NUM_VCLK_DPM_LEVELS; i++)
1593		dev_info(smu->adev->dev, "  .[%02d] = %d\n", i, pptable->FreqTableVclk[i]);
1594
1595	dev_info(smu->adev->dev, "FreqTableDclk\n");
1596	for (i = 0; i < NUM_DCLK_DPM_LEVELS; i++)
1597		dev_info(smu->adev->dev, "  .[%02d] = %d\n", i, pptable->FreqTableDclk[i]);
1598
1599	dev_info(smu->adev->dev, "FreqTableSocclk\n");
1600	for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++)
1601		dev_info(smu->adev->dev, "  .[%02d] = %d\n", i, pptable->FreqTableSocclk[i]);
1602
1603	dev_info(smu->adev->dev, "FreqTableUclk\n");
1604	for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
1605		dev_info(smu->adev->dev, "  .[%02d] = %d\n", i, pptable->FreqTableUclk[i]);
1606
1607	dev_info(smu->adev->dev, "FreqTableFclk\n");
1608	for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++)
1609		dev_info(smu->adev->dev, "  .[%02d] = %d\n", i, pptable->FreqTableFclk[i]);
1610
1611	dev_info(smu->adev->dev, "Mp0clkFreq\n");
1612	for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
1613		dev_info(smu->adev->dev, "  .[%d] = %d\n", i, pptable->Mp0clkFreq[i]);
1614
1615	dev_info(smu->adev->dev, "Mp0DpmVoltage\n");
1616	for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
1617		dev_info(smu->adev->dev, "  .[%d] = %d\n", i, pptable->Mp0DpmVoltage[i]);
1618
1619	dev_info(smu->adev->dev, "GfxclkFidle = 0x%x\n", pptable->GfxclkFidle);
1620	dev_info(smu->adev->dev, "GfxclkSlewRate = 0x%x\n", pptable->GfxclkSlewRate);
1621	dev_info(smu->adev->dev, "Padding567[0] = 0x%x\n", pptable->Padding567[0]);
1622	dev_info(smu->adev->dev, "Padding567[1] = 0x%x\n", pptable->Padding567[1]);
1623	dev_info(smu->adev->dev, "Padding567[2] = 0x%x\n", pptable->Padding567[2]);
1624	dev_info(smu->adev->dev, "Padding567[3] = 0x%x\n", pptable->Padding567[3]);
1625	dev_info(smu->adev->dev, "GfxclkDsMaxFreq = %d\n", pptable->GfxclkDsMaxFreq);
1626	dev_info(smu->adev->dev, "GfxclkSource = 0x%x\n", pptable->GfxclkSource);
1627	dev_info(smu->adev->dev, "Padding456 = 0x%x\n", pptable->Padding456);
1628
1629	dev_info(smu->adev->dev, "EnableTdpm = %d\n", pptable->EnableTdpm);
1630	dev_info(smu->adev->dev, "TdpmHighHystTemperature = %d\n", pptable->TdpmHighHystTemperature);
1631	dev_info(smu->adev->dev, "TdpmLowHystTemperature = %d\n", pptable->TdpmLowHystTemperature);
1632	dev_info(smu->adev->dev, "GfxclkFreqHighTempLimit = %d\n", pptable->GfxclkFreqHighTempLimit);
1633
1634	dev_info(smu->adev->dev, "FanStopTemp = %d\n", pptable->FanStopTemp);
1635	dev_info(smu->adev->dev, "FanStartTemp = %d\n", pptable->FanStartTemp);
1636
1637	dev_info(smu->adev->dev, "FanGainEdge = %d\n", pptable->FanGainEdge);
1638	dev_info(smu->adev->dev, "FanGainHotspot = %d\n", pptable->FanGainHotspot);
1639	dev_info(smu->adev->dev, "FanGainVrGfx = %d\n", pptable->FanGainVrGfx);
1640	dev_info(smu->adev->dev, "FanGainVrSoc = %d\n", pptable->FanGainVrSoc);
1641	dev_info(smu->adev->dev, "FanGainVrMem = %d\n", pptable->FanGainVrMem);
1642	dev_info(smu->adev->dev, "FanGainHbm = %d\n", pptable->FanGainHbm);
1643
1644	dev_info(smu->adev->dev, "FanPwmMin = %d\n", pptable->FanPwmMin);
1645	dev_info(smu->adev->dev, "FanAcousticLimitRpm = %d\n", pptable->FanAcousticLimitRpm);
1646	dev_info(smu->adev->dev, "FanThrottlingRpm = %d\n", pptable->FanThrottlingRpm);
1647	dev_info(smu->adev->dev, "FanMaximumRpm = %d\n", pptable->FanMaximumRpm);
1648	dev_info(smu->adev->dev, "FanTargetTemperature = %d\n", pptable->FanTargetTemperature);
1649	dev_info(smu->adev->dev, "FanTargetGfxclk = %d\n", pptable->FanTargetGfxclk);
1650	dev_info(smu->adev->dev, "FanZeroRpmEnable = %d\n", pptable->FanZeroRpmEnable);
1651	dev_info(smu->adev->dev, "FanTachEdgePerRev = %d\n", pptable->FanTachEdgePerRev);
1652	dev_info(smu->adev->dev, "FanTempInputSelect = %d\n", pptable->FanTempInputSelect);
1653
1654	dev_info(smu->adev->dev, "FuzzyFan_ErrorSetDelta = %d\n", pptable->FuzzyFan_ErrorSetDelta);
1655	dev_info(smu->adev->dev, "FuzzyFan_ErrorRateSetDelta = %d\n", pptable->FuzzyFan_ErrorRateSetDelta);
1656	dev_info(smu->adev->dev, "FuzzyFan_PwmSetDelta = %d\n", pptable->FuzzyFan_PwmSetDelta);
1657	dev_info(smu->adev->dev, "FuzzyFan_Reserved = %d\n", pptable->FuzzyFan_Reserved);
1658
1659	dev_info(smu->adev->dev, "OverrideAvfsGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_GFX]);
1660	dev_info(smu->adev->dev, "OverrideAvfsGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_SOC]);
1661	dev_info(smu->adev->dev, "Padding8_Avfs[0] = %d\n", pptable->Padding8_Avfs[0]);
1662	dev_info(smu->adev->dev, "Padding8_Avfs[1] = %d\n", pptable->Padding8_Avfs[1]);
1663
1664	dev_info(smu->adev->dev, "dBtcGbGfxPll{a = 0x%x b = 0x%x c = 0x%x}\n",
1665			pptable->dBtcGbGfxPll.a,
1666			pptable->dBtcGbGfxPll.b,
1667			pptable->dBtcGbGfxPll.c);
1668	dev_info(smu->adev->dev, "dBtcGbGfxAfll{a = 0x%x b = 0x%x c = 0x%x}\n",
1669			pptable->dBtcGbGfxAfll.a,
1670			pptable->dBtcGbGfxAfll.b,
1671			pptable->dBtcGbGfxAfll.c);
1672	dev_info(smu->adev->dev, "dBtcGbSoc{a = 0x%x b = 0x%x c = 0x%x}\n",
1673			pptable->dBtcGbSoc.a,
1674			pptable->dBtcGbSoc.b,
1675			pptable->dBtcGbSoc.c);
1676
1677	dev_info(smu->adev->dev, "qAgingGb[AVFS_VOLTAGE_GFX]{m = 0x%x b = 0x%x}\n",
1678			pptable->qAgingGb[AVFS_VOLTAGE_GFX].m,
1679			pptable->qAgingGb[AVFS_VOLTAGE_GFX].b);
1680	dev_info(smu->adev->dev, "qAgingGb[AVFS_VOLTAGE_SOC]{m = 0x%x b = 0x%x}\n",
1681			pptable->qAgingGb[AVFS_VOLTAGE_SOC].m,
1682			pptable->qAgingGb[AVFS_VOLTAGE_SOC].b);
1683
1684	dev_info(smu->adev->dev, "qStaticVoltageOffset[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
1685			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].a,
1686			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].b,
1687			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].c);
1688	dev_info(smu->adev->dev, "qStaticVoltageOffset[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
1689			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].a,
1690			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].b,
1691			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].c);
1692
1693	dev_info(smu->adev->dev, "DcTol[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_GFX]);
1694	dev_info(smu->adev->dev, "DcTol[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_SOC]);
1695
1696	dev_info(smu->adev->dev, "DcBtcEnabled[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_GFX]);
1697	dev_info(smu->adev->dev, "DcBtcEnabled[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_SOC]);
1698	dev_info(smu->adev->dev, "Padding8_GfxBtc[0] = 0x%x\n", pptable->Padding8_GfxBtc[0]);
1699	dev_info(smu->adev->dev, "Padding8_GfxBtc[1] = 0x%x\n", pptable->Padding8_GfxBtc[1]);
1700
1701	dev_info(smu->adev->dev, "DcBtcMin[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_GFX]);
1702	dev_info(smu->adev->dev, "DcBtcMin[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_SOC]);
1703	dev_info(smu->adev->dev, "DcBtcMax[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_GFX]);
1704	dev_info(smu->adev->dev, "DcBtcMax[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_SOC]);
1705
1706	dev_info(smu->adev->dev, "DcBtcGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_GFX]);
1707	dev_info(smu->adev->dev, "DcBtcGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_SOC]);
1708
1709	dev_info(smu->adev->dev, "XgmiDpmPstates\n");
1710	for (i = 0; i < NUM_XGMI_LEVELS; i++)
1711		dev_info(smu->adev->dev, "  .[%d] = %d\n", i, pptable->XgmiDpmPstates[i]);
1712	dev_info(smu->adev->dev, "XgmiDpmSpare[0] = 0x%02x\n", pptable->XgmiDpmSpare[0]);
1713	dev_info(smu->adev->dev, "XgmiDpmSpare[1] = 0x%02x\n", pptable->XgmiDpmSpare[1]);
1714
1715	dev_info(smu->adev->dev, "VDDGFX_TVmin = %d\n", pptable->VDDGFX_TVmin);
1716	dev_info(smu->adev->dev, "VDDSOC_TVmin = %d\n", pptable->VDDSOC_TVmin);
1717	dev_info(smu->adev->dev, "VDDGFX_Vmin_HiTemp = %d\n", pptable->VDDGFX_Vmin_HiTemp);
1718	dev_info(smu->adev->dev, "VDDGFX_Vmin_LoTemp = %d\n", pptable->VDDGFX_Vmin_LoTemp);
1719	dev_info(smu->adev->dev, "VDDSOC_Vmin_HiTemp = %d\n", pptable->VDDSOC_Vmin_HiTemp);
1720	dev_info(smu->adev->dev, "VDDSOC_Vmin_LoTemp = %d\n", pptable->VDDSOC_Vmin_LoTemp);
1721	dev_info(smu->adev->dev, "VDDGFX_TVminHystersis = %d\n", pptable->VDDGFX_TVminHystersis);
1722	dev_info(smu->adev->dev, "VDDSOC_TVminHystersis = %d\n", pptable->VDDSOC_TVminHystersis);
1723
1724	dev_info(smu->adev->dev, "DebugOverrides = 0x%x\n", pptable->DebugOverrides);
1725	dev_info(smu->adev->dev, "ReservedEquation0{a = 0x%x b = 0x%x c = 0x%x}\n",
1726			pptable->ReservedEquation0.a,
1727			pptable->ReservedEquation0.b,
1728			pptable->ReservedEquation0.c);
1729	dev_info(smu->adev->dev, "ReservedEquation1{a = 0x%x b = 0x%x c = 0x%x}\n",
1730			pptable->ReservedEquation1.a,
1731			pptable->ReservedEquation1.b,
1732			pptable->ReservedEquation1.c);
1733	dev_info(smu->adev->dev, "ReservedEquation2{a = 0x%x b = 0x%x c = 0x%x}\n",
1734			pptable->ReservedEquation2.a,
1735			pptable->ReservedEquation2.b,
1736			pptable->ReservedEquation2.c);
1737	dev_info(smu->adev->dev, "ReservedEquation3{a = 0x%x b = 0x%x c = 0x%x}\n",
1738			pptable->ReservedEquation3.a,
1739			pptable->ReservedEquation3.b,
1740			pptable->ReservedEquation3.c);
1741
1742	dev_info(smu->adev->dev, "MinVoltageUlvGfx = %d\n", pptable->MinVoltageUlvGfx);
1743	dev_info(smu->adev->dev, "PaddingUlv = %d\n", pptable->PaddingUlv);
1744
1745	dev_info(smu->adev->dev, "TotalPowerConfig = %d\n", pptable->TotalPowerConfig);
1746	dev_info(smu->adev->dev, "TotalPowerSpare1 = %d\n", pptable->TotalPowerSpare1);
1747	dev_info(smu->adev->dev, "TotalPowerSpare2 = %d\n", pptable->TotalPowerSpare2);
1748
1749	dev_info(smu->adev->dev, "PccThresholdLow = %d\n", pptable->PccThresholdLow);
1750	dev_info(smu->adev->dev, "PccThresholdHigh = %d\n", pptable->PccThresholdHigh);
1751
1752	dev_info(smu->adev->dev, "Board Parameters:\n");
1753	dev_info(smu->adev->dev, "MaxVoltageStepGfx = 0x%x\n", pptable->MaxVoltageStepGfx);
1754	dev_info(smu->adev->dev, "MaxVoltageStepSoc = 0x%x\n", pptable->MaxVoltageStepSoc);
1755
1756	dev_info(smu->adev->dev, "VddGfxVrMapping = 0x%x\n", pptable->VddGfxVrMapping);
1757	dev_info(smu->adev->dev, "VddSocVrMapping = 0x%x\n", pptable->VddSocVrMapping);
1758	dev_info(smu->adev->dev, "VddMemVrMapping = 0x%x\n", pptable->VddMemVrMapping);
1759	dev_info(smu->adev->dev, "BoardVrMapping = 0x%x\n", pptable->BoardVrMapping);
1760
1761	dev_info(smu->adev->dev, "GfxUlvPhaseSheddingMask = 0x%x\n", pptable->GfxUlvPhaseSheddingMask);
1762	dev_info(smu->adev->dev, "ExternalSensorPresent = 0x%x\n", pptable->ExternalSensorPresent);
1763
1764	dev_info(smu->adev->dev, "GfxMaxCurrent = 0x%x\n", pptable->GfxMaxCurrent);
1765	dev_info(smu->adev->dev, "GfxOffset = 0x%x\n", pptable->GfxOffset);
1766	dev_info(smu->adev->dev, "Padding_TelemetryGfx = 0x%x\n", pptable->Padding_TelemetryGfx);
1767
1768	dev_info(smu->adev->dev, "SocMaxCurrent = 0x%x\n", pptable->SocMaxCurrent);
1769	dev_info(smu->adev->dev, "SocOffset = 0x%x\n", pptable->SocOffset);
1770	dev_info(smu->adev->dev, "Padding_TelemetrySoc = 0x%x\n", pptable->Padding_TelemetrySoc);
1771
1772	dev_info(smu->adev->dev, "MemMaxCurrent = 0x%x\n", pptable->MemMaxCurrent);
1773	dev_info(smu->adev->dev, "MemOffset = 0x%x\n", pptable->MemOffset);
1774	dev_info(smu->adev->dev, "Padding_TelemetryMem = 0x%x\n", pptable->Padding_TelemetryMem);
1775
1776	dev_info(smu->adev->dev, "BoardMaxCurrent = 0x%x\n", pptable->BoardMaxCurrent);
1777	dev_info(smu->adev->dev, "BoardOffset = 0x%x\n", pptable->BoardOffset);
1778	dev_info(smu->adev->dev, "Padding_TelemetryBoardInput = 0x%x\n", pptable->Padding_TelemetryBoardInput);
1779
1780	dev_info(smu->adev->dev, "VR0HotGpio = %d\n", pptable->VR0HotGpio);
1781	dev_info(smu->adev->dev, "VR0HotPolarity = %d\n", pptable->VR0HotPolarity);
1782	dev_info(smu->adev->dev, "VR1HotGpio = %d\n", pptable->VR1HotGpio);
1783	dev_info(smu->adev->dev, "VR1HotPolarity = %d\n", pptable->VR1HotPolarity);
1784
1785	dev_info(smu->adev->dev, "PllGfxclkSpreadEnabled = %d\n", pptable->PllGfxclkSpreadEnabled);
1786	dev_info(smu->adev->dev, "PllGfxclkSpreadPercent = %d\n", pptable->PllGfxclkSpreadPercent);
1787	dev_info(smu->adev->dev, "PllGfxclkSpreadFreq = %d\n", pptable->PllGfxclkSpreadFreq);
1788
1789	dev_info(smu->adev->dev, "UclkSpreadEnabled = %d\n", pptable->UclkSpreadEnabled);
1790	dev_info(smu->adev->dev, "UclkSpreadPercent = %d\n", pptable->UclkSpreadPercent);
1791	dev_info(smu->adev->dev, "UclkSpreadFreq = %d\n", pptable->UclkSpreadFreq);
1792
1793	dev_info(smu->adev->dev, "FclkSpreadEnabled = %d\n", pptable->FclkSpreadEnabled);
1794	dev_info(smu->adev->dev, "FclkSpreadPercent = %d\n", pptable->FclkSpreadPercent);
1795	dev_info(smu->adev->dev, "FclkSpreadFreq = %d\n", pptable->FclkSpreadFreq);
1796
1797	dev_info(smu->adev->dev, "FllGfxclkSpreadEnabled = %d\n", pptable->FllGfxclkSpreadEnabled);
1798	dev_info(smu->adev->dev, "FllGfxclkSpreadPercent = %d\n", pptable->FllGfxclkSpreadPercent);
1799	dev_info(smu->adev->dev, "FllGfxclkSpreadFreq = %d\n", pptable->FllGfxclkSpreadFreq);
1800
1801	for (i = 0; i < NUM_I2C_CONTROLLERS; i++) {
1802		dev_info(smu->adev->dev, "I2cControllers[%d]:\n", i);
1803		dev_info(smu->adev->dev, "                   .Enabled = %d\n",
1804				pptable->I2cControllers[i].Enabled);
1805		dev_info(smu->adev->dev, "                   .SlaveAddress = 0x%x\n",
1806				pptable->I2cControllers[i].SlaveAddress);
1807		dev_info(smu->adev->dev, "                   .ControllerPort = %d\n",
1808				pptable->I2cControllers[i].ControllerPort);
1809		dev_info(smu->adev->dev, "                   .ControllerName = %d\n",
1810				pptable->I2cControllers[i].ControllerName);
1811		dev_info(smu->adev->dev, "                   .ThermalThrottler = %d\n",
1812				pptable->I2cControllers[i].ThermalThrotter);
1813		dev_info(smu->adev->dev, "                   .I2cProtocol = %d\n",
1814				pptable->I2cControllers[i].I2cProtocol);
1815		dev_info(smu->adev->dev, "                   .Speed = %d\n",
1816				pptable->I2cControllers[i].Speed);
1817	}
1818
1819	dev_info(smu->adev->dev, "MemoryChannelEnabled = %d\n", pptable->MemoryChannelEnabled);
1820	dev_info(smu->adev->dev, "DramBitWidth = %d\n", pptable->DramBitWidth);
1821
1822	dev_info(smu->adev->dev, "TotalBoardPower = %d\n", pptable->TotalBoardPower);
1823
1824	dev_info(smu->adev->dev, "XgmiLinkSpeed\n");
1825	for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1826		dev_info(smu->adev->dev, "  .[%d] = %d\n", i, pptable->XgmiLinkSpeed[i]);
1827	dev_info(smu->adev->dev, "XgmiLinkWidth\n");
1828	for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1829		dev_info(smu->adev->dev, "  .[%d] = %d\n", i, pptable->XgmiLinkWidth[i]);
1830	dev_info(smu->adev->dev, "XgmiFclkFreq\n");
1831	for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1832		dev_info(smu->adev->dev, "  .[%d] = %d\n", i, pptable->XgmiFclkFreq[i]);
1833	dev_info(smu->adev->dev, "XgmiSocVoltage\n");
1834	for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1835		dev_info(smu->adev->dev, "  .[%d] = %d\n", i, pptable->XgmiSocVoltage[i]);
1836
1837}
1838
1839static bool arcturus_is_dpm_running(struct smu_context *smu)
1840{
1841	int ret = 0;
1842	uint32_t feature_mask[2];
1843	uint64_t feature_enabled;
1844
1845	ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2);
1846	if (ret)
1847		return false;
1848
1849	feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0];
1850
1851	return !!(feature_enabled & SMC_DPM_FEATURE);
1852}
1853
1854static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
1855{
1856	int ret = 0;
1857
1858	if (enable) {
1859		if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
1860			ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 1);
1861			if (ret) {
1862				dev_err(smu->adev->dev, "[EnableVCNDPM] failed!\n");
1863				return ret;
1864			}
1865		}
1866	} else {
1867		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
1868			ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 0);
1869			if (ret) {
1870				dev_err(smu->adev->dev, "[DisableVCNDPM] failed!\n");
1871				return ret;
1872			}
1873		}
1874	}
1875
1876	return ret;
1877}
1878
1879static void arcturus_fill_i2c_req(SwI2cRequest_t  *req, bool write,
1880				  uint8_t address, uint32_t numbytes,
1881				  uint8_t *data)
1882{
1883	int i;
1884
1885	req->I2CcontrollerPort = 0;
1886	req->I2CSpeed = 2;
1887	req->SlaveAddress = address;
1888	req->NumCmds = numbytes;
1889
1890	for (i = 0; i < numbytes; i++) {
1891		SwI2cCmd_t *cmd =  &req->SwI2cCmds[i];
1892
1893		/* First 2 bytes are always write for lower 2b EEPROM address */
1894		if (i < 2)
1895			cmd->Cmd = 1;
1896		else
1897			cmd->Cmd = write;
1898
1899
1900		/* Add RESTART for read  after address filled */
1901		cmd->CmdConfig |= (i == 2 && !write) ? CMDCONFIG_RESTART_MASK : 0;
1902
1903		/* Add STOP in the end */
1904		cmd->CmdConfig |= (i == (numbytes - 1)) ? CMDCONFIG_STOP_MASK : 0;
1905
1906		/* Fill with data regardless if read or write to simplify code */
1907		cmd->RegisterAddr = data[i];
1908	}
1909}
1910
1911static int arcturus_i2c_read_data(struct i2c_adapter *control,
1912					       uint8_t address,
1913					       uint8_t *data,
1914					       uint32_t numbytes)
1915{
1916	uint32_t  i, ret = 0;
1917	SwI2cRequest_t req;
1918	struct amdgpu_device *adev = to_amdgpu_device(control);
1919	struct smu_table_context *smu_table = &adev->smu.smu_table;
1920	struct smu_table *table = &smu_table->driver_table;
1921
1922	if (numbytes > MAX_SW_I2C_COMMANDS) {
1923		dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
1924			numbytes, MAX_SW_I2C_COMMANDS);
1925		return -EINVAL;
1926	}
1927
1928	memset(&req, 0, sizeof(req));
1929	arcturus_fill_i2c_req(&req, false, address, numbytes, data);
1930
1931	mutex_lock(&adev->smu.mutex);
1932	/* Now read data starting with that address */
1933	ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req,
1934					true);
1935	mutex_unlock(&adev->smu.mutex);
1936
1937	if (!ret) {
1938		SwI2cRequest_t *res = (SwI2cRequest_t *)table->cpu_addr;
1939
1940		/* Assume SMU  fills res.SwI2cCmds[i].Data with read bytes */
1941		for (i = 0; i < numbytes; i++)
1942			data[i] = res->SwI2cCmds[i].Data;
1943
1944		dev_dbg(adev->dev, "arcturus_i2c_read_data, address = %x, bytes = %d, data :",
1945				  (uint16_t)address, numbytes);
1946
1947		print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
1948			       8, 1, data, numbytes, false);
1949	} else
1950		dev_err(adev->dev, "arcturus_i2c_read_data - error occurred :%x", ret);
1951
1952	return ret;
1953}
1954
1955static int arcturus_i2c_write_data(struct i2c_adapter *control,
1956						uint8_t address,
1957						uint8_t *data,
1958						uint32_t numbytes)
1959{
1960	uint32_t ret;
1961	SwI2cRequest_t req;
1962	struct amdgpu_device *adev = to_amdgpu_device(control);
1963
1964	if (numbytes > MAX_SW_I2C_COMMANDS) {
1965		dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
1966			numbytes, MAX_SW_I2C_COMMANDS);
1967		return -EINVAL;
1968	}
1969
1970	memset(&req, 0, sizeof(req));
1971	arcturus_fill_i2c_req(&req, true, address, numbytes, data);
1972
1973	mutex_lock(&adev->smu.mutex);
1974	ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req, true);
1975	mutex_unlock(&adev->smu.mutex);
1976
1977	if (!ret) {
1978		dev_dbg(adev->dev, "arcturus_i2c_write(), address = %x, bytes = %d , data: ",
1979					 (uint16_t)address, numbytes);
1980
1981		print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
1982			       8, 1, data, numbytes, false);
1983		/*
1984		 * According to EEPROM spec there is a MAX of 10 ms required for
1985		 * EEPROM to flush internal RX buffer after STOP was issued at the
1986		 * end of write transaction. During this time the EEPROM will not be
1987		 * responsive to any more commands - so wait a bit more.
1988		 */
1989		msleep(10);
1990
1991	} else
1992		dev_err(adev->dev, "arcturus_i2c_write- error occurred :%x", ret);
1993
1994	return ret;
1995}
1996
1997static int arcturus_i2c_xfer(struct i2c_adapter *i2c_adap,
1998			      struct i2c_msg *msgs, int num)
1999{
2000	uint32_t  i, j, ret, data_size, data_chunk_size, next_eeprom_addr = 0;
2001	uint8_t *data_ptr, data_chunk[MAX_SW_I2C_COMMANDS] = { 0 };
2002
2003	for (i = 0; i < num; i++) {
2004		/*
2005		 * SMU interface allows at most MAX_SW_I2C_COMMANDS bytes of data at
2006		 * once and hence the data needs to be spliced into chunks and sent each
2007		 * chunk separately
2008		 */
2009		data_size = msgs[i].len - 2;
2010		data_chunk_size = MAX_SW_I2C_COMMANDS - 2;
2011		next_eeprom_addr = (msgs[i].buf[0] << 8 & 0xff00) | (msgs[i].buf[1] & 0xff);
2012		data_ptr = msgs[i].buf + 2;
2013
2014		for (j = 0; j < data_size / data_chunk_size; j++) {
2015			/* Insert the EEPROM dest addess, bits 0-15 */
2016			data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2017			data_chunk[1] = (next_eeprom_addr & 0xff);
2018
2019			if (msgs[i].flags & I2C_M_RD) {
2020				ret = arcturus_i2c_read_data(i2c_adap,
2021							     (uint8_t)msgs[i].addr,
2022							     data_chunk, MAX_SW_I2C_COMMANDS);
2023
2024				memcpy(data_ptr, data_chunk + 2, data_chunk_size);
2025			} else {
2026
2027				memcpy(data_chunk + 2, data_ptr, data_chunk_size);
2028
2029				ret = arcturus_i2c_write_data(i2c_adap,
2030							      (uint8_t)msgs[i].addr,
2031							      data_chunk, MAX_SW_I2C_COMMANDS);
2032			}
2033
2034			if (ret) {
2035				num = -EIO;
2036				goto fail;
2037			}
2038
2039			next_eeprom_addr += data_chunk_size;
2040			data_ptr += data_chunk_size;
2041		}
2042
2043		if (data_size % data_chunk_size) {
2044			data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2045			data_chunk[1] = (next_eeprom_addr & 0xff);
2046
2047			if (msgs[i].flags & I2C_M_RD) {
2048				ret = arcturus_i2c_read_data(i2c_adap,
2049							     (uint8_t)msgs[i].addr,
2050							     data_chunk, (data_size % data_chunk_size) + 2);
2051
2052				memcpy(data_ptr, data_chunk + 2, data_size % data_chunk_size);
2053			} else {
2054				memcpy(data_chunk + 2, data_ptr, data_size % data_chunk_size);
2055
2056				ret = arcturus_i2c_write_data(i2c_adap,
2057							      (uint8_t)msgs[i].addr,
2058							      data_chunk, (data_size % data_chunk_size) + 2);
2059			}
2060
2061			if (ret) {
2062				num = -EIO;
2063				goto fail;
2064			}
2065		}
2066	}
2067
2068fail:
2069	return num;
2070}
2071
2072static u32 arcturus_i2c_func(struct i2c_adapter *adap)
2073{
2074	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
2075}
2076
2077
2078static const struct i2c_algorithm arcturus_i2c_algo = {
2079	.master_xfer = arcturus_i2c_xfer,
2080	.functionality = arcturus_i2c_func,
2081};
2082
2083static int arcturus_i2c_control_init(struct smu_context *smu, struct i2c_adapter *control)
2084{
2085	struct amdgpu_device *adev = to_amdgpu_device(control);
2086	int res;
2087
2088	control->owner = THIS_MODULE;
2089	control->class = I2C_CLASS_SPD;
2090	control->dev.parent = &adev->pdev->dev;
2091	control->algo = &arcturus_i2c_algo;
2092	snprintf(control->name, sizeof(control->name), "AMDGPU SMU");
2093
2094	res = i2c_add_adapter(control);
2095	if (res)
2096		DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
2097
2098	return res;
2099}
2100
2101static void arcturus_i2c_control_fini(struct smu_context *smu, struct i2c_adapter *control)
2102{
2103	i2c_del_adapter(control);
2104}
2105
2106static void arcturus_get_unique_id(struct smu_context *smu)
2107{
2108	struct amdgpu_device *adev = smu->adev;
2109	uint32_t top32 = 0, bottom32 = 0, smu_version;
2110	uint64_t id;
2111
2112	if (smu_cmn_get_smc_version(smu, NULL, &smu_version)) {
2113		dev_warn(adev->dev, "Failed to get smu version, cannot get unique_id or serial_number\n");
2114		return;
2115	}
2116
2117	/* PPSMC_MSG_ReadSerial* is supported by 54.23.0 and onwards */
2118	if (smu_version < 0x361700) {
2119		dev_warn(adev->dev, "ReadSerial is only supported by PMFW 54.23.0 and onwards\n");
2120		return;
2121	}
2122
2123	/* Get the SN to turn into a Unique ID */
2124	smu_cmn_send_smc_msg(smu, SMU_MSG_ReadSerialNumTop32, &top32);
2125	smu_cmn_send_smc_msg(smu, SMU_MSG_ReadSerialNumBottom32, &bottom32);
2126
2127	id = ((uint64_t)bottom32 << 32) | top32;
2128	adev->unique_id = id;
2129	/* For Arcturus-and-later, unique_id == serial_number, so convert it to a
2130	 * 16-digit HEX string for convenience and backwards-compatibility
2131	 */
2132	sprintf(adev->serial, "%llx", id);
2133}
2134
2135static bool arcturus_is_baco_supported(struct smu_context *smu)
2136{
2137	struct amdgpu_device *adev = smu->adev;
2138	uint32_t val;
2139
2140	if (!smu_v11_0_baco_is_support(smu) || amdgpu_sriov_vf(adev))
2141		return false;
2142
2143	val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
2144	return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false;
2145}
2146
2147static int arcturus_set_df_cstate(struct smu_context *smu,
2148				  enum pp_df_cstate state)
2149{
2150	uint32_t smu_version;
2151	int ret;
2152
2153	ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
2154	if (ret) {
2155		dev_err(smu->adev->dev, "Failed to get smu version!\n");
2156		return ret;
2157	}
2158
2159	/* PPSMC_MSG_DFCstateControl is supported by 54.15.0 and onwards */
2160	if (smu_version < 0x360F00) {
2161		dev_err(smu->adev->dev, "DFCstateControl is only supported by PMFW 54.15.0 and onwards\n");
2162		return -EINVAL;
2163	}
2164
2165	return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state, NULL);
2166}
2167
2168static int arcturus_allow_xgmi_power_down(struct smu_context *smu, bool en)
2169{
2170	uint32_t smu_version;
2171	int ret;
2172
2173	ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
2174	if (ret) {
2175		dev_err(smu->adev->dev, "Failed to get smu version!\n");
2176		return ret;
2177	}
2178
2179	/* PPSMC_MSG_GmiPwrDnControl is supported by 54.23.0 and onwards */
2180	if (smu_version < 0x00361700) {
2181		dev_err(smu->adev->dev, "XGMI power down control is only supported by PMFW 54.23.0 and onwards\n");
2182		return -EINVAL;
2183	}
2184
2185	if (en)
2186		return smu_cmn_send_smc_msg_with_param(smu,
2187						   SMU_MSG_GmiPwrDnControl,
2188						   1,
2189						   NULL);
2190
2191	return smu_cmn_send_smc_msg_with_param(smu,
2192					   SMU_MSG_GmiPwrDnControl,
2193					   0,
2194					   NULL);
2195}
2196
2197static const struct throttling_logging_label {
2198	uint32_t feature_mask;
2199	const char *label;
2200} logging_label[] = {
2201	{(1U << THROTTLER_TEMP_HOTSPOT_BIT), "GPU"},
2202	{(1U << THROTTLER_TEMP_MEM_BIT), "HBM"},
2203	{(1U << THROTTLER_TEMP_VR_GFX_BIT), "VR of GFX rail"},
2204	{(1U << THROTTLER_TEMP_VR_MEM_BIT), "VR of HBM rail"},
2205	{(1U << THROTTLER_TEMP_VR_SOC_BIT), "VR of SOC rail"},
2206	{(1U << THROTTLER_VRHOT0_BIT), "VR0 HOT"},
2207	{(1U << THROTTLER_VRHOT1_BIT), "VR1 HOT"},
2208};
2209static void arcturus_log_thermal_throttling_event(struct smu_context *smu)
2210{
2211	int ret;
2212	int throttler_idx, throtting_events = 0, buf_idx = 0;
2213	struct amdgpu_device *adev = smu->adev;
2214	uint32_t throttler_status;
2215	char log_buf[256];
2216
2217	ret = arcturus_get_smu_metrics_data(smu,
2218					    METRICS_THROTTLER_STATUS,
2219					    &throttler_status);
2220	if (ret)
2221		return;
2222
2223	memset(log_buf, 0, sizeof(log_buf));
2224	for (throttler_idx = 0; throttler_idx < ARRAY_SIZE(logging_label);
2225	     throttler_idx++) {
2226		if (throttler_status & logging_label[throttler_idx].feature_mask) {
2227			throtting_events++;
2228			buf_idx += snprintf(log_buf + buf_idx,
2229					    sizeof(log_buf) - buf_idx,
2230					    "%s%s",
2231					    throtting_events > 1 ? " and " : "",
2232					    logging_label[throttler_idx].label);
2233			if (buf_idx >= sizeof(log_buf)) {
2234				dev_err(adev->dev, "buffer overflow!\n");
2235				log_buf[sizeof(log_buf) - 1] = '\0';
2236				break;
2237			}
2238		}
2239	}
2240
2241	dev_warn(adev->dev, "WARN: GPU thermal throttling temperature reached, expect performance decrease. %s.\n",
2242			log_buf);
2243}
2244
2245static const struct pptable_funcs arcturus_ppt_funcs = {
2246	/* init dpm */
2247	.get_allowed_feature_mask = arcturus_get_allowed_feature_mask,
2248	/* btc */
2249	.run_btc = arcturus_run_btc,
2250	/* dpm/clk tables */
2251	.set_default_dpm_table = arcturus_set_default_dpm_table,
2252	.populate_umd_state_clk = arcturus_populate_umd_state_clk,
2253	.get_thermal_temperature_range = arcturus_get_thermal_temperature_range,
2254	.print_clk_levels = arcturus_print_clk_levels,
2255	.force_clk_levels = arcturus_force_clk_levels,
2256	.read_sensor = arcturus_read_sensor,
2257	.get_fan_speed_percent = arcturus_get_fan_speed_percent,
2258	.get_fan_speed_rpm = arcturus_get_fan_speed_rpm,
2259	.get_power_profile_mode = arcturus_get_power_profile_mode,
2260	.set_power_profile_mode = arcturus_set_power_profile_mode,
2261	.set_performance_level = arcturus_set_performance_level,
2262	/* debug (internal used) */
2263	.dump_pptable = arcturus_dump_pptable,
2264	.get_power_limit = arcturus_get_power_limit,
2265	.is_dpm_running = arcturus_is_dpm_running,
2266	.dpm_set_vcn_enable = arcturus_dpm_set_vcn_enable,
2267	.i2c_init = arcturus_i2c_control_init,
2268	.i2c_fini = arcturus_i2c_control_fini,
2269	.get_unique_id = arcturus_get_unique_id,
2270	.init_microcode = smu_v11_0_init_microcode,
2271	.load_microcode = smu_v11_0_load_microcode,
2272	.fini_microcode = smu_v11_0_fini_microcode,
2273	.init_smc_tables = arcturus_init_smc_tables,
2274	.fini_smc_tables = smu_v11_0_fini_smc_tables,
2275	.init_power = smu_v11_0_init_power,
2276	.fini_power = smu_v11_0_fini_power,
2277	.check_fw_status = smu_v11_0_check_fw_status,
2278	/* pptable related */
2279	.setup_pptable = arcturus_setup_pptable,
2280	.get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
2281	.check_fw_version = smu_v11_0_check_fw_version,
2282	.write_pptable = smu_cmn_write_pptable,
2283	.set_driver_table_location = smu_v11_0_set_driver_table_location,
2284	.set_tool_table_location = smu_v11_0_set_tool_table_location,
2285	.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
2286	.system_features_control = smu_v11_0_system_features_control,
2287	.send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
2288	.send_smc_msg = smu_cmn_send_smc_msg,
2289	.init_display_count = NULL,
2290	.set_allowed_mask = smu_v11_0_set_allowed_mask,
2291	.get_enabled_mask = smu_cmn_get_enabled_mask,
2292	.feature_is_enabled = smu_cmn_feature_is_enabled,
2293	.disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception,
2294	.notify_display_change = NULL,
2295	.set_power_limit = smu_v11_0_set_power_limit,
2296	.init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
2297	.enable_thermal_alert = smu_v11_0_enable_thermal_alert,
2298	.disable_thermal_alert = smu_v11_0_disable_thermal_alert,
2299	.set_min_dcef_deep_sleep = NULL,
2300	.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
2301	.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
2302	.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
2303	.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
2304	.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
2305	.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
2306	.gfx_off_control = smu_v11_0_gfx_off_control,
2307	.register_irq_handler = smu_v11_0_register_irq_handler,
2308	.set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
2309	.get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
2310	.baco_is_support= arcturus_is_baco_supported,
2311	.baco_get_state = smu_v11_0_baco_get_state,
2312	.baco_set_state = smu_v11_0_baco_set_state,
2313	.baco_enter = smu_v11_0_baco_enter,
2314	.baco_exit = smu_v11_0_baco_exit,
2315	.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
2316	.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
2317	.set_df_cstate = arcturus_set_df_cstate,
2318	.allow_xgmi_power_down = arcturus_allow_xgmi_power_down,
2319	.log_thermal_throttling_event = arcturus_log_thermal_throttling_event,
2320	.get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
2321	.set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
2322};
2323
2324void arcturus_set_ppt_funcs(struct smu_context *smu)
2325{
2326	smu->ppt_funcs = &arcturus_ppt_funcs;
2327	smu->message_map = arcturus_message_map;
2328	smu->clock_map = arcturus_clk_map;
2329	smu->feature_map = arcturus_feature_mask_map;
2330	smu->table_map = arcturus_table_map;
2331	smu->pwr_src_map = arcturus_pwr_src_map;
2332	smu->workload_map = arcturus_workload_map;
2333}