Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   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 <linux/pci.h>
  28#include <linux/i2c.h>
  29#include "amdgpu.h"
  30#include "amdgpu_smu.h"
  31#include "atomfirmware.h"
  32#include "amdgpu_atomfirmware.h"
  33#include "amdgpu_atombios.h"
  34#include "smu_v11_0.h"
  35#include "smu11_driver_if_sienna_cichlid.h"
  36#include "soc15_common.h"
  37#include "atom.h"
  38#include "sienna_cichlid_ppt.h"
  39#include "smu_v11_0_7_pptable.h"
  40#include "smu_v11_0_7_ppsmc.h"
  41#include "nbio/nbio_2_3_offset.h"
  42#include "nbio/nbio_2_3_sh_mask.h"
  43#include "thm/thm_11_0_2_offset.h"
  44#include "thm/thm_11_0_2_sh_mask.h"
  45#include "mp/mp_11_0_offset.h"
  46#include "mp/mp_11_0_sh_mask.h"
  47
  48#include "asic_reg/mp/mp_11_0_sh_mask.h"
  49#include "smu_cmn.h"
  50
  51/*
  52 * DO NOT use these for err/warn/info/debug messages.
  53 * Use dev_err, dev_warn, dev_info and dev_dbg instead.
  54 * They are more MGPU friendly.
  55 */
  56#undef pr_err
  57#undef pr_warn
  58#undef pr_info
  59#undef pr_debug
  60
  61#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
  62
  63#define FEATURE_MASK(feature) (1ULL << feature)
  64#define SMC_DPM_FEATURE ( \
  65	FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) | \
  66	FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT)     | \
  67	FEATURE_MASK(FEATURE_DPM_UCLK_BIT)	 | \
  68	FEATURE_MASK(FEATURE_DPM_LINK_BIT)       | \
  69	FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT)     | \
  70	FEATURE_MASK(FEATURE_DPM_FCLK_BIT)	 | \
  71	FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)	 | \
  72	FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT))
  73
  74#define SMU_11_0_7_GFX_BUSY_THRESHOLD 15
  75
  76static struct cmn2asic_msg_mapping sienna_cichlid_message_map[SMU_MSG_MAX_COUNT] = {
  77	MSG_MAP(TestMessage,			PPSMC_MSG_TestMessage,                 1),
  78	MSG_MAP(GetSmuVersion,			PPSMC_MSG_GetSmuVersion,               1),
  79	MSG_MAP(GetDriverIfVersion,		PPSMC_MSG_GetDriverIfVersion,          1),
  80	MSG_MAP(SetAllowedFeaturesMaskLow,	PPSMC_MSG_SetAllowedFeaturesMaskLow,   0),
  81	MSG_MAP(SetAllowedFeaturesMaskHigh,	PPSMC_MSG_SetAllowedFeaturesMaskHigh,  0),
  82	MSG_MAP(EnableAllSmuFeatures,		PPSMC_MSG_EnableAllSmuFeatures,        0),
  83	MSG_MAP(DisableAllSmuFeatures,		PPSMC_MSG_DisableAllSmuFeatures,       0),
  84	MSG_MAP(EnableSmuFeaturesLow,		PPSMC_MSG_EnableSmuFeaturesLow,        1),
  85	MSG_MAP(EnableSmuFeaturesHigh,		PPSMC_MSG_EnableSmuFeaturesHigh,       1),
  86	MSG_MAP(DisableSmuFeaturesLow,		PPSMC_MSG_DisableSmuFeaturesLow,       1),
  87	MSG_MAP(DisableSmuFeaturesHigh,		PPSMC_MSG_DisableSmuFeaturesHigh,      1),
  88	MSG_MAP(GetEnabledSmuFeaturesLow,       PPSMC_MSG_GetRunningSmuFeaturesLow,    1),
  89	MSG_MAP(GetEnabledSmuFeaturesHigh,	PPSMC_MSG_GetRunningSmuFeaturesHigh,   1),
  90	MSG_MAP(SetWorkloadMask,		PPSMC_MSG_SetWorkloadMask,             1),
  91	MSG_MAP(SetPptLimit,			PPSMC_MSG_SetPptLimit,                 0),
  92	MSG_MAP(SetDriverDramAddrHigh,		PPSMC_MSG_SetDriverDramAddrHigh,       0),
  93	MSG_MAP(SetDriverDramAddrLow,		PPSMC_MSG_SetDriverDramAddrLow,        0),
  94	MSG_MAP(SetToolsDramAddrHigh,		PPSMC_MSG_SetToolsDramAddrHigh,        0),
  95	MSG_MAP(SetToolsDramAddrLow,		PPSMC_MSG_SetToolsDramAddrLow,         0),
  96	MSG_MAP(TransferTableSmu2Dram,		PPSMC_MSG_TransferTableSmu2Dram,       0),
  97	MSG_MAP(TransferTableDram2Smu,		PPSMC_MSG_TransferTableDram2Smu,       0),
  98	MSG_MAP(UseDefaultPPTable,		PPSMC_MSG_UseDefaultPPTable,           0),
  99	MSG_MAP(RunDcBtc,			PPSMC_MSG_RunDcBtc,                    0),
 100	MSG_MAP(EnterBaco,			PPSMC_MSG_EnterBaco,                   0),
 101	MSG_MAP(SetSoftMinByFreq,		PPSMC_MSG_SetSoftMinByFreq,            0),
 102	MSG_MAP(SetSoftMaxByFreq,		PPSMC_MSG_SetSoftMaxByFreq,            0),
 103	MSG_MAP(SetHardMinByFreq,		PPSMC_MSG_SetHardMinByFreq,            1),
 104	MSG_MAP(SetHardMaxByFreq,		PPSMC_MSG_SetHardMaxByFreq,            0),
 105	MSG_MAP(GetMinDpmFreq,			PPSMC_MSG_GetMinDpmFreq,               1),
 106	MSG_MAP(GetMaxDpmFreq,			PPSMC_MSG_GetMaxDpmFreq,               1),
 107	MSG_MAP(GetDpmFreqByIndex,		PPSMC_MSG_GetDpmFreqByIndex,           1),
 108	MSG_MAP(SetGeminiMode,			PPSMC_MSG_SetGeminiMode,               0),
 109	MSG_MAP(SetGeminiApertureHigh,		PPSMC_MSG_SetGeminiApertureHigh,       0),
 110	MSG_MAP(SetGeminiApertureLow,		PPSMC_MSG_SetGeminiApertureLow,        0),
 111	MSG_MAP(OverridePcieParameters,		PPSMC_MSG_OverridePcieParameters,      0),
 112	MSG_MAP(ReenableAcDcInterrupt,		PPSMC_MSG_ReenableAcDcInterrupt,       0),
 113	MSG_MAP(NotifyPowerSource,		PPSMC_MSG_NotifyPowerSource,           0),
 114	MSG_MAP(SetUclkFastSwitch,		PPSMC_MSG_SetUclkFastSwitch,           0),
 115	MSG_MAP(SetVideoFps,			PPSMC_MSG_SetVideoFps,                 0),
 116	MSG_MAP(PrepareMp1ForUnload,		PPSMC_MSG_PrepareMp1ForUnload,         1),
 117	MSG_MAP(AllowGfxOff,			PPSMC_MSG_AllowGfxOff,                 0),
 118	MSG_MAP(DisallowGfxOff,			PPSMC_MSG_DisallowGfxOff,              0),
 119	MSG_MAP(GetPptLimit,			PPSMC_MSG_GetPptLimit,                 0),
 120	MSG_MAP(GetDcModeMaxDpmFreq,		PPSMC_MSG_GetDcModeMaxDpmFreq,         1),
 121	MSG_MAP(ExitBaco,			PPSMC_MSG_ExitBaco,                    0),
 122	MSG_MAP(PowerUpVcn,			PPSMC_MSG_PowerUpVcn,                  0),
 123	MSG_MAP(PowerDownVcn,			PPSMC_MSG_PowerDownVcn,                0),
 124	MSG_MAP(PowerUpJpeg,			PPSMC_MSG_PowerUpJpeg,                 0),
 125	MSG_MAP(PowerDownJpeg,			PPSMC_MSG_PowerDownJpeg,               0),
 126	MSG_MAP(BacoAudioD3PME,			PPSMC_MSG_BacoAudioD3PME,              0),
 127	MSG_MAP(ArmD3,				PPSMC_MSG_ArmD3,                       0),
 128	MSG_MAP(Mode1Reset,                     PPSMC_MSG_Mode1Reset,		       0),
 129};
 130
 131static struct cmn2asic_mapping sienna_cichlid_clk_map[SMU_CLK_COUNT] = {
 132	CLK_MAP(GFXCLK,		PPCLK_GFXCLK),
 133	CLK_MAP(SCLK,		PPCLK_GFXCLK),
 134	CLK_MAP(SOCCLK,		PPCLK_SOCCLK),
 135	CLK_MAP(FCLK,		PPCLK_FCLK),
 136	CLK_MAP(UCLK,		PPCLK_UCLK),
 137	CLK_MAP(MCLK,		PPCLK_UCLK),
 138	CLK_MAP(DCLK,		PPCLK_DCLK_0),
 139	CLK_MAP(DCLK1,		PPCLK_DCLK_1),
 140	CLK_MAP(VCLK,		PPCLK_VCLK_0),
 141	CLK_MAP(VCLK1,		PPCLK_VCLK_1),
 142	CLK_MAP(DCEFCLK,	PPCLK_DCEFCLK),
 143	CLK_MAP(DISPCLK,	PPCLK_DISPCLK),
 144	CLK_MAP(PIXCLK,		PPCLK_PIXCLK),
 145	CLK_MAP(PHYCLK,		PPCLK_PHYCLK),
 146};
 147
 148static struct cmn2asic_mapping sienna_cichlid_feature_mask_map[SMU_FEATURE_COUNT] = {
 149	FEA_MAP(DPM_PREFETCHER),
 150	FEA_MAP(DPM_GFXCLK),
 151	FEA_MAP(DPM_GFX_GPO),
 152	FEA_MAP(DPM_UCLK),
 153	FEA_MAP(DPM_SOCCLK),
 154	FEA_MAP(DPM_MP0CLK),
 155	FEA_MAP(DPM_LINK),
 156	FEA_MAP(DPM_DCEFCLK),
 157	FEA_MAP(MEM_VDDCI_SCALING),
 158	FEA_MAP(MEM_MVDD_SCALING),
 159	FEA_MAP(DS_GFXCLK),
 160	FEA_MAP(DS_SOCCLK),
 161	FEA_MAP(DS_LCLK),
 162	FEA_MAP(DS_DCEFCLK),
 163	FEA_MAP(DS_UCLK),
 164	FEA_MAP(GFX_ULV),
 165	FEA_MAP(FW_DSTATE),
 166	FEA_MAP(GFXOFF),
 167	FEA_MAP(BACO),
 168	FEA_MAP(MM_DPM_PG),
 169	FEA_MAP(RSMU_SMN_CG),
 170	FEA_MAP(PPT),
 171	FEA_MAP(TDC),
 172	FEA_MAP(APCC_PLUS),
 173	FEA_MAP(GTHR),
 174	FEA_MAP(ACDC),
 175	FEA_MAP(VR0HOT),
 176	FEA_MAP(VR1HOT),
 177	FEA_MAP(FW_CTF),
 178	FEA_MAP(FAN_CONTROL),
 179	FEA_MAP(THERMAL),
 180	FEA_MAP(GFX_DCS),
 181	FEA_MAP(RM),
 182	FEA_MAP(LED_DISPLAY),
 183	FEA_MAP(GFX_SS),
 184	FEA_MAP(OUT_OF_BAND_MONITOR),
 185	FEA_MAP(TEMP_DEPENDENT_VMIN),
 186	FEA_MAP(MMHUB_PG),
 187	FEA_MAP(ATHUB_PG),
 188	FEA_MAP(APCC_DFLL),
 189};
 190
 191static struct cmn2asic_mapping sienna_cichlid_table_map[SMU_TABLE_COUNT] = {
 192	TAB_MAP(PPTABLE),
 193	TAB_MAP(WATERMARKS),
 194	TAB_MAP(AVFS_PSM_DEBUG),
 195	TAB_MAP(AVFS_FUSE_OVERRIDE),
 196	TAB_MAP(PMSTATUSLOG),
 197	TAB_MAP(SMU_METRICS),
 198	TAB_MAP(DRIVER_SMU_CONFIG),
 199	TAB_MAP(ACTIVITY_MONITOR_COEFF),
 200	TAB_MAP(OVERDRIVE),
 201	TAB_MAP(I2C_COMMANDS),
 202	TAB_MAP(PACE),
 203};
 204
 205static struct cmn2asic_mapping sienna_cichlid_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
 206	PWR_MAP(AC),
 207	PWR_MAP(DC),
 208};
 209
 210static struct cmn2asic_mapping sienna_cichlid_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
 211	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT,	WORKLOAD_PPLIB_DEFAULT_BIT),
 212	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D,		WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
 213	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING,		WORKLOAD_PPLIB_POWER_SAVING_BIT),
 214	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,		WORKLOAD_PPLIB_VIDEO_BIT),
 215	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR,			WORKLOAD_PPLIB_VR_BIT),
 216	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,		WORKLOAD_PPLIB_CUSTOM_BIT),
 217	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,		WORKLOAD_PPLIB_CUSTOM_BIT),
 218};
 219
 220static int
 221sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu,
 222				  uint32_t *feature_mask, uint32_t num)
 223{
 224	struct amdgpu_device *adev = smu->adev;
 225
 226	if (num > 2)
 227		return -EINVAL;
 228
 229	memset(feature_mask, 0, sizeof(uint32_t) * num);
 230
 231	*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT)
 232				| FEATURE_MASK(FEATURE_DPM_FCLK_BIT)
 233				| FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)
 234				| FEATURE_MASK(FEATURE_DS_SOCCLK_BIT)
 235				| FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT)
 236				| FEATURE_MASK(FEATURE_DS_FCLK_BIT)
 237				| FEATURE_MASK(FEATURE_DS_UCLK_BIT)
 238				| FEATURE_MASK(FEATURE_FW_DSTATE_BIT)
 239				| FEATURE_MASK(FEATURE_DF_CSTATE_BIT)
 240				| FEATURE_MASK(FEATURE_RSMU_SMN_CG_BIT)
 241				| FEATURE_MASK(FEATURE_GFX_SS_BIT)
 242				| FEATURE_MASK(FEATURE_VR0HOT_BIT)
 243				| FEATURE_MASK(FEATURE_PPT_BIT)
 244				| FEATURE_MASK(FEATURE_TDC_BIT)
 245				| FEATURE_MASK(FEATURE_BACO_BIT)
 246				| FEATURE_MASK(FEATURE_APCC_DFLL_BIT)
 247				| FEATURE_MASK(FEATURE_FW_CTF_BIT)
 248				| FEATURE_MASK(FEATURE_FAN_CONTROL_BIT)
 249				| FEATURE_MASK(FEATURE_THERMAL_BIT)
 250				| FEATURE_MASK(FEATURE_OUT_OF_BAND_MONITOR_BIT);
 251
 252	if (adev->pm.pp_feature & PP_SCLK_DPM_MASK) {
 253		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT);
 254		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFX_GPO_BIT);
 255	}
 256
 257	if (adev->pm.pp_feature & PP_MCLK_DPM_MASK)
 258		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT)
 259					| FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT)
 260					| FEATURE_MASK(FEATURE_MEM_MVDD_SCALING_BIT);
 261
 262	if (adev->pm.pp_feature & PP_PCIE_DPM_MASK)
 263		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_LINK_BIT);
 264
 265	if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK)
 266		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT);
 267
 268	if (adev->pm.pp_feature & PP_SOCCLK_DPM_MASK)
 269		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT);
 270
 271	if (adev->pm.pp_feature & PP_ULV_MASK)
 272		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_ULV_BIT);
 273
 274	if (adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK)
 275		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_GFXCLK_BIT);
 276
 277	if (adev->pm.pp_feature & PP_GFXOFF_MASK)
 278		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXOFF_BIT);
 279
 280	if (smu->adev->pg_flags & AMD_PG_SUPPORT_ATHUB)
 281		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ATHUB_PG_BIT);
 282
 283	if (smu->adev->pg_flags & AMD_PG_SUPPORT_MMHUB)
 284		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MMHUB_PG_BIT);
 285
 286	if (smu->adev->pg_flags & AMD_PG_SUPPORT_VCN ||
 287	    smu->adev->pg_flags & AMD_PG_SUPPORT_JPEG)
 288		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MM_DPM_PG_BIT);
 289
 290	return 0;
 291}
 292
 293static int sienna_cichlid_check_powerplay_table(struct smu_context *smu)
 294{
 295	struct smu_table_context *table_context = &smu->smu_table;
 296	struct smu_11_0_7_powerplay_table *powerplay_table =
 297		table_context->power_play_table;
 298	struct smu_baco_context *smu_baco = &smu->smu_baco;
 299
 300	mutex_lock(&smu_baco->mutex);
 301	if (powerplay_table->platform_caps & SMU_11_0_7_PP_PLATFORM_CAP_BACO ||
 302	    powerplay_table->platform_caps & SMU_11_0_7_PP_PLATFORM_CAP_MACO)
 303		smu_baco->platform_support = true;
 304	mutex_unlock(&smu_baco->mutex);
 305
 306	table_context->thermal_controller_type =
 307		powerplay_table->thermal_controller_type;
 308
 309	return 0;
 310}
 311
 312static int sienna_cichlid_append_powerplay_table(struct smu_context *smu)
 313{
 314	struct smu_table_context *table_context = &smu->smu_table;
 315	PPTable_t *smc_pptable = table_context->driver_pptable;
 316	struct atom_smc_dpm_info_v4_9 *smc_dpm_table;
 317	int index, ret;
 318
 319	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 320					    smc_dpm_info);
 321
 322	ret = amdgpu_atombios_get_data_table(smu->adev, index, NULL, NULL, NULL,
 323				      (uint8_t **)&smc_dpm_table);
 324	if (ret)
 325		return ret;
 326
 327	memcpy(smc_pptable->I2cControllers, smc_dpm_table->I2cControllers,
 328	       sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header));
 329	
 330	return 0;
 331}
 332
 333static int sienna_cichlid_store_powerplay_table(struct smu_context *smu)
 334{
 335	struct smu_table_context *table_context = &smu->smu_table;
 336	struct smu_11_0_7_powerplay_table *powerplay_table =
 337		table_context->power_play_table;
 338
 339	memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
 340	       sizeof(PPTable_t));
 341
 342	return 0;
 343}
 344
 345static int sienna_cichlid_setup_pptable(struct smu_context *smu)
 346{
 347	int ret = 0;
 348
 349	ret = smu_v11_0_setup_pptable(smu);
 350	if (ret)
 351		return ret;
 352
 353	ret = sienna_cichlid_store_powerplay_table(smu);
 354	if (ret)
 355		return ret;
 356
 357	ret = sienna_cichlid_append_powerplay_table(smu);
 358	if (ret)
 359		return ret;
 360
 361	ret = sienna_cichlid_check_powerplay_table(smu);
 362	if (ret)
 363		return ret;
 364
 365	return ret;
 366}
 367
 368static int sienna_cichlid_tables_init(struct smu_context *smu)
 369{
 370	struct smu_table_context *smu_table = &smu->smu_table;
 371	struct smu_table *tables = smu_table->tables;
 372
 373	SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
 374		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 375	SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
 376		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 377	SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
 378		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 379	SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
 380		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 381	SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTable_t),
 382		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 383	SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE,
 384		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 385	SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF,
 386		       sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE,
 387	               AMDGPU_GEM_DOMAIN_VRAM);
 388
 389	smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
 390	if (!smu_table->metrics_table)
 391		return -ENOMEM;
 392	smu_table->metrics_time = 0;
 393
 394	smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
 395	if (!smu_table->watermarks_table)
 396		return -ENOMEM;
 397
 398	return 0;
 399}
 400
 401static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu,
 402					       MetricsMember_t member,
 403					       uint32_t *value)
 404{
 405	struct smu_table_context *smu_table= &smu->smu_table;
 406	SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
 407	int ret = 0;
 408
 409	mutex_lock(&smu->metrics_lock);
 410	if (!smu_table->metrics_time ||
 411	     time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(1))) {
 412		ret = smu_cmn_update_table(smu,
 413				       SMU_TABLE_SMU_METRICS,
 414				       0,
 415				       smu_table->metrics_table,
 416				       false);
 417		if (ret) {
 418			dev_info(smu->adev->dev, "Failed to export SMU metrics table!\n");
 419			mutex_unlock(&smu->metrics_lock);
 420			return ret;
 421		}
 422		smu_table->metrics_time = jiffies;
 423	}
 424
 425	switch (member) {
 426	case METRICS_CURR_GFXCLK:
 427		*value = metrics->CurrClock[PPCLK_GFXCLK];
 428		break;
 429	case METRICS_CURR_SOCCLK:
 430		*value = metrics->CurrClock[PPCLK_SOCCLK];
 431		break;
 432	case METRICS_CURR_UCLK:
 433		*value = metrics->CurrClock[PPCLK_UCLK];
 434		break;
 435	case METRICS_CURR_VCLK:
 436		*value = metrics->CurrClock[PPCLK_VCLK_0];
 437		break;
 438	case METRICS_CURR_VCLK1:
 439		*value = metrics->CurrClock[PPCLK_VCLK_1];
 440		break;
 441	case METRICS_CURR_DCLK:
 442		*value = metrics->CurrClock[PPCLK_DCLK_0];
 443		break;
 444	case METRICS_CURR_DCLK1:
 445		*value = metrics->CurrClock[PPCLK_DCLK_1];
 446		break;
 447	case METRICS_CURR_DCEFCLK:
 448		*value = metrics->CurrClock[PPCLK_DCEFCLK];
 449		break;
 450	case METRICS_AVERAGE_GFXCLK:
 451		if (metrics->AverageGfxActivity <= SMU_11_0_7_GFX_BUSY_THRESHOLD)
 452			*value = metrics->AverageGfxclkFrequencyPostDs;
 453		else
 454			*value = metrics->AverageGfxclkFrequencyPreDs;
 455		break;
 456	case METRICS_AVERAGE_FCLK:
 457		*value = metrics->AverageFclkFrequencyPostDs;
 458		break;
 459	case METRICS_AVERAGE_UCLK:
 460		*value = metrics->AverageUclkFrequencyPostDs;
 461		break;
 462	case METRICS_AVERAGE_GFXACTIVITY:
 463		*value = metrics->AverageGfxActivity;
 464		break;
 465	case METRICS_AVERAGE_MEMACTIVITY:
 466		*value = metrics->AverageUclkActivity;
 467		break;
 468	case METRICS_AVERAGE_SOCKETPOWER:
 469		*value = metrics->AverageSocketPower << 8;
 470		break;
 471	case METRICS_TEMPERATURE_EDGE:
 472		*value = metrics->TemperatureEdge *
 473			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 474		break;
 475	case METRICS_TEMPERATURE_HOTSPOT:
 476		*value = metrics->TemperatureHotspot *
 477			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 478		break;
 479	case METRICS_TEMPERATURE_MEM:
 480		*value = metrics->TemperatureMem *
 481			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 482		break;
 483	case METRICS_TEMPERATURE_VRGFX:
 484		*value = metrics->TemperatureVrGfx *
 485			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 486		break;
 487	case METRICS_TEMPERATURE_VRSOC:
 488		*value = metrics->TemperatureVrSoc *
 489			SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
 490		break;
 491	case METRICS_THROTTLER_STATUS:
 492		*value = metrics->ThrottlerStatus;
 493		break;
 494	case METRICS_CURR_FANSPEED:
 495		*value = metrics->CurrFanSpeed;
 496		break;
 497	default:
 498		*value = UINT_MAX;
 499		break;
 500	}
 501
 502	mutex_unlock(&smu->metrics_lock);
 503
 504	return ret;
 505
 506}
 507
 508static int sienna_cichlid_allocate_dpm_context(struct smu_context *smu)
 509{
 510	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
 511
 512	smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context),
 513				       GFP_KERNEL);
 514	if (!smu_dpm->dpm_context)
 515		return -ENOMEM;
 516
 517	smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context);
 518
 519	return 0;
 520}
 521
 522static int sienna_cichlid_init_smc_tables(struct smu_context *smu)
 523{
 524	int ret = 0;
 525
 526	ret = sienna_cichlid_tables_init(smu);
 527	if (ret)
 528		return ret;
 529
 530	ret = sienna_cichlid_allocate_dpm_context(smu);
 531	if (ret)
 532		return ret;
 533
 534	return smu_v11_0_init_smc_tables(smu);
 535}
 536
 537static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu)
 538{
 539	struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
 540	PPTable_t *driver_ppt = smu->smu_table.driver_pptable;
 541	struct smu_11_0_dpm_table *dpm_table;
 542	struct amdgpu_device *adev = smu->adev;
 543	int ret = 0;
 544
 545	/* socclk dpm table setup */
 546	dpm_table = &dpm_context->dpm_tables.soc_table;
 547	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
 548		ret = smu_v11_0_set_single_dpm_table(smu,
 549						     SMU_SOCCLK,
 550						     dpm_table);
 551		if (ret)
 552			return ret;
 553		dpm_table->is_fine_grained =
 554			!driver_ppt->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete;
 555	} else {
 556		dpm_table->count = 1;
 557		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
 558		dpm_table->dpm_levels[0].enabled = true;
 559		dpm_table->min = dpm_table->dpm_levels[0].value;
 560		dpm_table->max = dpm_table->dpm_levels[0].value;
 561	}
 562
 563	/* gfxclk dpm table setup */
 564	dpm_table = &dpm_context->dpm_tables.gfx_table;
 565	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
 566		ret = smu_v11_0_set_single_dpm_table(smu,
 567						     SMU_GFXCLK,
 568						     dpm_table);
 569		if (ret)
 570			return ret;
 571		dpm_table->is_fine_grained =
 572			!driver_ppt->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete;
 573	} else {
 574		dpm_table->count = 1;
 575		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
 576		dpm_table->dpm_levels[0].enabled = true;
 577		dpm_table->min = dpm_table->dpm_levels[0].value;
 578		dpm_table->max = dpm_table->dpm_levels[0].value;
 579	}
 580
 581	/* uclk dpm table setup */
 582	dpm_table = &dpm_context->dpm_tables.uclk_table;
 583	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
 584		ret = smu_v11_0_set_single_dpm_table(smu,
 585						     SMU_UCLK,
 586						     dpm_table);
 587		if (ret)
 588			return ret;
 589		dpm_table->is_fine_grained =
 590			!driver_ppt->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete;
 591	} else {
 592		dpm_table->count = 1;
 593		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
 594		dpm_table->dpm_levels[0].enabled = true;
 595		dpm_table->min = dpm_table->dpm_levels[0].value;
 596		dpm_table->max = dpm_table->dpm_levels[0].value;
 597	}
 598
 599	/* fclk dpm table setup */
 600	dpm_table = &dpm_context->dpm_tables.fclk_table;
 601	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
 602		ret = smu_v11_0_set_single_dpm_table(smu,
 603						     SMU_FCLK,
 604						     dpm_table);
 605		if (ret)
 606			return ret;
 607		dpm_table->is_fine_grained =
 608			!driver_ppt->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete;
 609	} else {
 610		dpm_table->count = 1;
 611		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.fclk / 100;
 612		dpm_table->dpm_levels[0].enabled = true;
 613		dpm_table->min = dpm_table->dpm_levels[0].value;
 614		dpm_table->max = dpm_table->dpm_levels[0].value;
 615	}
 616
 617	/* vclk0 dpm table setup */
 618	dpm_table = &dpm_context->dpm_tables.vclk_table;
 619	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
 620		ret = smu_v11_0_set_single_dpm_table(smu,
 621						     SMU_VCLK,
 622						     dpm_table);
 623		if (ret)
 624			return ret;
 625		dpm_table->is_fine_grained =
 626			!driver_ppt->DpmDescriptor[PPCLK_VCLK_0].SnapToDiscrete;
 627	} else {
 628		dpm_table->count = 1;
 629		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100;
 630		dpm_table->dpm_levels[0].enabled = true;
 631		dpm_table->min = dpm_table->dpm_levels[0].value;
 632		dpm_table->max = dpm_table->dpm_levels[0].value;
 633	}
 634
 635	/* vclk1 dpm table setup */
 636	if (adev->vcn.num_vcn_inst > 1) {
 637		dpm_table = &dpm_context->dpm_tables.vclk1_table;
 638		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
 639			ret = smu_v11_0_set_single_dpm_table(smu,
 640							     SMU_VCLK1,
 641							     dpm_table);
 642			if (ret)
 643				return ret;
 644			dpm_table->is_fine_grained =
 645				!driver_ppt->DpmDescriptor[PPCLK_VCLK_1].SnapToDiscrete;
 646		} else {
 647			dpm_table->count = 1;
 648			dpm_table->dpm_levels[0].value =
 649				smu->smu_table.boot_values.vclk / 100;
 650			dpm_table->dpm_levels[0].enabled = true;
 651			dpm_table->min = dpm_table->dpm_levels[0].value;
 652			dpm_table->max = dpm_table->dpm_levels[0].value;
 653		}
 654	}
 655
 656	/* dclk0 dpm table setup */
 657	dpm_table = &dpm_context->dpm_tables.dclk_table;
 658	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
 659		ret = smu_v11_0_set_single_dpm_table(smu,
 660						     SMU_DCLK,
 661						     dpm_table);
 662		if (ret)
 663			return ret;
 664		dpm_table->is_fine_grained =
 665			!driver_ppt->DpmDescriptor[PPCLK_DCLK_0].SnapToDiscrete;
 666	} else {
 667		dpm_table->count = 1;
 668		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100;
 669		dpm_table->dpm_levels[0].enabled = true;
 670		dpm_table->min = dpm_table->dpm_levels[0].value;
 671		dpm_table->max = dpm_table->dpm_levels[0].value;
 672	}
 673
 674	/* dclk1 dpm table setup */
 675	if (adev->vcn.num_vcn_inst > 1) {
 676		dpm_table = &dpm_context->dpm_tables.dclk1_table;
 677		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
 678			ret = smu_v11_0_set_single_dpm_table(smu,
 679							     SMU_DCLK1,
 680							     dpm_table);
 681			if (ret)
 682				return ret;
 683			dpm_table->is_fine_grained =
 684				!driver_ppt->DpmDescriptor[PPCLK_DCLK_1].SnapToDiscrete;
 685		} else {
 686			dpm_table->count = 1;
 687			dpm_table->dpm_levels[0].value =
 688				smu->smu_table.boot_values.dclk / 100;
 689			dpm_table->dpm_levels[0].enabled = true;
 690			dpm_table->min = dpm_table->dpm_levels[0].value;
 691			dpm_table->max = dpm_table->dpm_levels[0].value;
 692		}
 693	}
 694
 695	/* dcefclk dpm table setup */
 696	dpm_table = &dpm_context->dpm_tables.dcef_table;
 697	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
 698		ret = smu_v11_0_set_single_dpm_table(smu,
 699						     SMU_DCEFCLK,
 700						     dpm_table);
 701		if (ret)
 702			return ret;
 703		dpm_table->is_fine_grained =
 704			!driver_ppt->DpmDescriptor[PPCLK_DCEFCLK].SnapToDiscrete;
 705	} else {
 706		dpm_table->count = 1;
 707		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
 708		dpm_table->dpm_levels[0].enabled = true;
 709		dpm_table->min = dpm_table->dpm_levels[0].value;
 710		dpm_table->max = dpm_table->dpm_levels[0].value;
 711	}
 712
 713	/* pixelclk dpm table setup */
 714	dpm_table = &dpm_context->dpm_tables.pixel_table;
 715	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
 716		ret = smu_v11_0_set_single_dpm_table(smu,
 717						     SMU_PIXCLK,
 718						     dpm_table);
 719		if (ret)
 720			return ret;
 721		dpm_table->is_fine_grained =
 722			!driver_ppt->DpmDescriptor[PPCLK_PIXCLK].SnapToDiscrete;
 723	} else {
 724		dpm_table->count = 1;
 725		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
 726		dpm_table->dpm_levels[0].enabled = true;
 727		dpm_table->min = dpm_table->dpm_levels[0].value;
 728		dpm_table->max = dpm_table->dpm_levels[0].value;
 729	}
 730
 731	/* displayclk dpm table setup */
 732	dpm_table = &dpm_context->dpm_tables.display_table;
 733	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
 734		ret = smu_v11_0_set_single_dpm_table(smu,
 735						     SMU_DISPCLK,
 736						     dpm_table);
 737		if (ret)
 738			return ret;
 739		dpm_table->is_fine_grained =
 740			!driver_ppt->DpmDescriptor[PPCLK_DISPCLK].SnapToDiscrete;
 741	} else {
 742		dpm_table->count = 1;
 743		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
 744		dpm_table->dpm_levels[0].enabled = true;
 745		dpm_table->min = dpm_table->dpm_levels[0].value;
 746		dpm_table->max = dpm_table->dpm_levels[0].value;
 747	}
 748
 749	/* phyclk dpm table setup */
 750	dpm_table = &dpm_context->dpm_tables.phy_table;
 751	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
 752		ret = smu_v11_0_set_single_dpm_table(smu,
 753						     SMU_PHYCLK,
 754						     dpm_table);
 755		if (ret)
 756			return ret;
 757		dpm_table->is_fine_grained =
 758			!driver_ppt->DpmDescriptor[PPCLK_PHYCLK].SnapToDiscrete;
 759	} else {
 760		dpm_table->count = 1;
 761		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
 762		dpm_table->dpm_levels[0].enabled = true;
 763		dpm_table->min = dpm_table->dpm_levels[0].value;
 764		dpm_table->max = dpm_table->dpm_levels[0].value;
 765	}
 766
 767	return 0;
 768}
 769
 770static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
 771{
 772	struct amdgpu_device *adev = smu->adev;
 773	int ret = 0;
 774
 775	if (enable) {
 776		/* vcn dpm on is a prerequisite for vcn power gate messages */
 777		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
 778			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL);
 779			if (ret)
 780				return ret;
 781			if (adev->vcn.num_vcn_inst > 1) {
 782				ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn,
 783								  0x10000, NULL);
 784				if (ret)
 785					return ret;
 786			}
 787		}
 788	} else {
 789		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
 790			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL);
 791			if (ret)
 792				return ret;
 793			if (adev->vcn.num_vcn_inst > 1) {
 794				ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn,
 795								  0x10000, NULL);
 796				if (ret)
 797					return ret;
 798			}
 799		}
 800	}
 801
 802	return ret;
 803}
 804
 805static int sienna_cichlid_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
 806{
 807	int ret = 0;
 808
 809	if (enable) {
 810		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
 811			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpJpeg, 0, NULL);
 812			if (ret)
 813				return ret;
 814		}
 815	} else {
 816		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
 817			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL);
 818			if (ret)
 819				return ret;
 820		}
 821	}
 822
 823	return ret;
 824}
 825
 826static int sienna_cichlid_get_current_clk_freq_by_table(struct smu_context *smu,
 827				       enum smu_clk_type clk_type,
 828				       uint32_t *value)
 829{
 830	MetricsMember_t member_type;
 831	int clk_id = 0;
 832
 833	clk_id = smu_cmn_to_asic_specific_index(smu,
 834						CMN2ASIC_MAPPING_CLK,
 835						clk_type);
 836	if (clk_id < 0)
 837		return clk_id;
 838
 839	switch (clk_id) {
 840	case PPCLK_GFXCLK:
 841		member_type = METRICS_CURR_GFXCLK;
 842		break;
 843	case PPCLK_UCLK:
 844		member_type = METRICS_CURR_UCLK;
 845		break;
 846	case PPCLK_SOCCLK:
 847		member_type = METRICS_CURR_SOCCLK;
 848		break;
 849	case PPCLK_FCLK:
 850		member_type = METRICS_CURR_FCLK;
 851		break;
 852	case PPCLK_VCLK_0:
 853		member_type = METRICS_CURR_VCLK;
 854		break;
 855	case PPCLK_VCLK_1:
 856		member_type = METRICS_CURR_VCLK1;
 857		break;
 858	case PPCLK_DCLK_0:
 859		member_type = METRICS_CURR_DCLK;
 860		break;
 861	case PPCLK_DCLK_1:
 862		member_type = METRICS_CURR_DCLK1;
 863		break;
 864	case PPCLK_DCEFCLK:
 865		member_type = METRICS_CURR_DCEFCLK;
 866		break;
 867	default:
 868		return -EINVAL;
 869	}
 870
 871	return sienna_cichlid_get_smu_metrics_data(smu,
 872						   member_type,
 873						   value);
 874
 875}
 876
 877static bool sienna_cichlid_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type)
 878{
 879	PPTable_t *pptable = smu->smu_table.driver_pptable;
 880	DpmDescriptor_t *dpm_desc = NULL;
 881	uint32_t clk_index = 0;
 882
 883	clk_index = smu_cmn_to_asic_specific_index(smu,
 884						   CMN2ASIC_MAPPING_CLK,
 885						   clk_type);
 886	dpm_desc = &pptable->DpmDescriptor[clk_index];
 887
 888	/* 0 - Fine grained DPM, 1 - Discrete DPM */
 889	return dpm_desc->SnapToDiscrete == 0 ? true : false;
 890}
 891
 892static int sienna_cichlid_print_clk_levels(struct smu_context *smu,
 893			enum smu_clk_type clk_type, char *buf)
 894{
 895	struct amdgpu_device *adev = smu->adev;
 896	struct smu_table_context *table_context = &smu->smu_table;
 897	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
 898	struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context;
 899	PPTable_t *pptable = (PPTable_t *)table_context->driver_pptable;
 900	int i, size = 0, ret = 0;
 901	uint32_t cur_value = 0, value = 0, count = 0;
 902	uint32_t freq_values[3] = {0};
 903	uint32_t mark_index = 0;
 904	uint32_t gen_speed, lane_width;
 905
 906	switch (clk_type) {
 907	case SMU_GFXCLK:
 908	case SMU_SCLK:
 909	case SMU_SOCCLK:
 910	case SMU_MCLK:
 911	case SMU_UCLK:
 912	case SMU_FCLK:
 913	case SMU_DCEFCLK:
 914		ret = sienna_cichlid_get_current_clk_freq_by_table(smu, clk_type, &cur_value);
 915		if (ret)
 916			goto print_clk_out;
 917
 918		/* no need to disable gfxoff when retrieving the current gfxclk */
 919		if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
 920			amdgpu_gfx_off_ctrl(adev, false);
 921
 922		ret = smu_v11_0_get_dpm_level_count(smu, clk_type, &count);
 923		if (ret)
 924			goto print_clk_out;
 925
 926		if (!sienna_cichlid_is_support_fine_grained_dpm(smu, clk_type)) {
 927			for (i = 0; i < count; i++) {
 928				ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
 929				if (ret)
 930					goto print_clk_out;
 931
 932				size += sprintf(buf + size, "%d: %uMhz %s\n", i, value,
 933						cur_value == value ? "*" : "");
 934			}
 935		} else {
 936			ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, 0, &freq_values[0]);
 937			if (ret)
 938				goto print_clk_out;
 939			ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, count - 1, &freq_values[2]);
 940			if (ret)
 941				goto print_clk_out;
 942
 943			freq_values[1] = cur_value;
 944			mark_index = cur_value == freq_values[0] ? 0 :
 945				     cur_value == freq_values[2] ? 2 : 1;
 946			if (mark_index != 1)
 947				freq_values[1] = (freq_values[0] + freq_values[2]) / 2;
 948
 949			for (i = 0; i < 3; i++) {
 950				size += sprintf(buf + size, "%d: %uMhz %s\n", i, freq_values[i],
 951						i == mark_index ? "*" : "");
 952			}
 953
 954		}
 955		break;
 956	case SMU_PCIE:
 957		gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) &
 958			     PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK)
 959			>> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;
 960		lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) &
 961			      PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK)
 962			>> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT;
 963		for (i = 0; i < NUM_LINK_LEVELS; i++)
 964			size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
 965					(dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," :
 966					(dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 1) ? "5.0GT/s," :
 967					(dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 2) ? "8.0GT/s," :
 968					(dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 3) ? "16.0GT/s," : "",
 969					(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 1) ? "x1" :
 970					(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 2) ? "x2" :
 971					(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 3) ? "x4" :
 972					(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 4) ? "x8" :
 973					(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 5) ? "x12" :
 974					(dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 6) ? "x16" : "",
 975					pptable->LclkFreq[i],
 976					(gen_speed == dpm_context->dpm_tables.pcie_table.pcie_gen[i]) &&
 977					(lane_width == dpm_context->dpm_tables.pcie_table.pcie_lane[i]) ?
 978					"*" : "");
 979		break;
 980	default:
 981		break;
 982	}
 983
 984print_clk_out:
 985	if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
 986		amdgpu_gfx_off_ctrl(adev, true);
 987
 988	return size;
 989}
 990
 991static int sienna_cichlid_force_clk_levels(struct smu_context *smu,
 992				   enum smu_clk_type clk_type, uint32_t mask)
 993{
 994	struct amdgpu_device *adev = smu->adev;
 995	int ret = 0, size = 0;
 996	uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0;
 997
 998	soft_min_level = mask ? (ffs(mask) - 1) : 0;
 999	soft_max_level = mask ? (fls(mask) - 1) : 0;
1000
1001	if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
1002		amdgpu_gfx_off_ctrl(adev, false);
1003
1004	switch (clk_type) {
1005	case SMU_GFXCLK:
1006	case SMU_SCLK:
1007	case SMU_SOCCLK:
1008	case SMU_MCLK:
1009	case SMU_UCLK:
1010	case SMU_DCEFCLK:
1011	case SMU_FCLK:
1012		/* There is only 2 levels for fine grained DPM */
1013		if (sienna_cichlid_is_support_fine_grained_dpm(smu, clk_type)) {
1014			soft_max_level = (soft_max_level >= 1 ? 1 : 0);
1015			soft_min_level = (soft_min_level >= 1 ? 1 : 0);
1016		}
1017
1018		ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq);
1019		if (ret)
1020			goto forec_level_out;
1021
1022		ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq);
1023		if (ret)
1024			goto forec_level_out;
1025
1026		ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
1027		if (ret)
1028			goto forec_level_out;
1029		break;
1030	default:
1031		break;
1032	}
1033
1034forec_level_out:
1035	if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
1036		amdgpu_gfx_off_ctrl(adev, true);
1037
1038	return size;
1039}
1040
1041static int sienna_cichlid_populate_umd_state_clk(struct smu_context *smu)
1042{
1043	struct smu_11_0_dpm_context *dpm_context =
1044				smu->smu_dpm.dpm_context;
1045	struct smu_11_0_dpm_table *gfx_table =
1046				&dpm_context->dpm_tables.gfx_table;
1047	struct smu_11_0_dpm_table *mem_table =
1048				&dpm_context->dpm_tables.uclk_table;
1049	struct smu_11_0_dpm_table *soc_table =
1050				&dpm_context->dpm_tables.soc_table;
1051	struct smu_umd_pstate_table *pstate_table =
1052				&smu->pstate_table;
1053
1054	pstate_table->gfxclk_pstate.min = gfx_table->min;
1055	pstate_table->gfxclk_pstate.peak = gfx_table->max;
1056
1057	pstate_table->uclk_pstate.min = mem_table->min;
1058	pstate_table->uclk_pstate.peak = mem_table->max;
1059
1060	pstate_table->socclk_pstate.min = soc_table->min;
1061	pstate_table->socclk_pstate.peak = soc_table->max;
1062
1063	return 0;
1064}
1065
1066static int sienna_cichlid_pre_display_config_changed(struct smu_context *smu)
1067{
1068	int ret = 0;
1069	uint32_t max_freq = 0;
1070
1071	/* Sienna_Cichlid do not support to change display num currently */
1072	return 0;
1073#if 0
1074	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, 0, NULL);
1075	if (ret)
1076		return ret;
1077#endif
1078
1079	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
1080		ret = smu_v11_0_get_dpm_ultimate_freq(smu, SMU_UCLK, NULL, &max_freq);
1081		if (ret)
1082			return ret;
1083		ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, 0, max_freq);
1084		if (ret)
1085			return ret;
1086	}
1087
1088	return ret;
1089}
1090
1091static int sienna_cichlid_display_config_changed(struct smu_context *smu)
1092{
1093	int ret = 0;
1094
1095	if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
1096	    smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
1097	    smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
1098#if 0
1099		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays,
1100						  smu->display_config->num_display,
1101						  NULL);
1102#endif
1103		if (ret)
1104			return ret;
1105	}
1106
1107	return ret;
1108}
1109
1110static int sienna_cichlid_get_gpu_power(struct smu_context *smu, uint32_t *value)
1111{
1112	if (!value)
1113		return -EINVAL;
1114
1115	return sienna_cichlid_get_smu_metrics_data(smu,
1116						   METRICS_AVERAGE_SOCKETPOWER,
1117						   value);
1118}
1119
1120static int sienna_cichlid_get_current_activity_percent(struct smu_context *smu,
1121					       enum amd_pp_sensors sensor,
1122					       uint32_t *value)
1123{
1124	int ret = 0;
1125
1126	if (!value)
1127		return -EINVAL;
1128
1129	switch (sensor) {
1130	case AMDGPU_PP_SENSOR_GPU_LOAD:
1131		ret = sienna_cichlid_get_smu_metrics_data(smu,
1132							  METRICS_AVERAGE_GFXACTIVITY,
1133							  value);
1134		break;
1135	case AMDGPU_PP_SENSOR_MEM_LOAD:
1136		ret = sienna_cichlid_get_smu_metrics_data(smu,
1137							  METRICS_AVERAGE_MEMACTIVITY,
1138							  value);
1139		break;
1140	default:
1141		dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n");
1142		return -EINVAL;
1143	}
1144
1145	return ret;
1146}
1147
1148static bool sienna_cichlid_is_dpm_running(struct smu_context *smu)
1149{
1150	int ret = 0;
1151	uint32_t feature_mask[2];
1152	uint64_t feature_enabled;
1153
1154	ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2);
1155	if (ret)
1156		return false;
1157
1158	feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0];
1159
1160	return !!(feature_enabled & SMC_DPM_FEATURE);
1161}
1162
1163static int sienna_cichlid_get_fan_speed_rpm(struct smu_context *smu,
1164				    uint32_t *speed)
1165{
1166	if (!speed)
1167		return -EINVAL;
1168
1169	return sienna_cichlid_get_smu_metrics_data(smu,
1170						   METRICS_CURR_FANSPEED,
1171						   speed);
1172}
1173
1174static int sienna_cichlid_get_fan_speed_percent(struct smu_context *smu,
1175					uint32_t *speed)
1176{
1177	int ret = 0;
1178	uint32_t percent = 0;
1179	uint32_t current_rpm;
1180	PPTable_t *pptable = smu->smu_table.driver_pptable;
1181
1182	ret = sienna_cichlid_get_fan_speed_rpm(smu, &current_rpm);
1183	if (ret)
1184		return ret;
1185
1186	percent = current_rpm * 100 / pptable->FanMaximumRpm;
1187	*speed = percent > 100 ? 100 : percent;
1188
1189	return ret;
1190}
1191
1192static int sienna_cichlid_get_power_profile_mode(struct smu_context *smu, char *buf)
1193{
1194	DpmActivityMonitorCoeffInt_t activity_monitor;
1195	uint32_t i, size = 0;
1196	int16_t workload_type = 0;
1197	static const char *profile_name[] = {
1198					"BOOTUP_DEFAULT",
1199					"3D_FULL_SCREEN",
1200					"POWER_SAVING",
1201					"VIDEO",
1202					"VR",
1203					"COMPUTE",
1204					"CUSTOM"};
1205	static const char *title[] = {
1206			"PROFILE_INDEX(NAME)",
1207			"CLOCK_TYPE(NAME)",
1208			"FPS",
1209			"MinFreqType",
1210			"MinActiveFreqType",
1211			"MinActiveFreq",
1212			"BoosterFreqType",
1213			"BoosterFreq",
1214			"PD_Data_limit_c",
1215			"PD_Data_error_coeff",
1216			"PD_Data_error_rate_coeff"};
1217	int result = 0;
1218
1219	if (!buf)
1220		return -EINVAL;
1221
1222	size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n",
1223			title[0], title[1], title[2], title[3], title[4], title[5],
1224			title[6], title[7], title[8], title[9], title[10]);
1225
1226	for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
1227		/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1228		workload_type = smu_cmn_to_asic_specific_index(smu,
1229							       CMN2ASIC_MAPPING_WORKLOAD,
1230							       i);
1231		if (workload_type < 0)
1232			return -EINVAL;
1233
1234		result = smu_cmn_update_table(smu,
1235					  SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
1236					  (void *)(&activity_monitor), false);
1237		if (result) {
1238			dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1239			return result;
1240		}
1241
1242		size += sprintf(buf + size, "%2d %14s%s:\n",
1243			i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
1244
1245		size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1246			" ",
1247			0,
1248			"GFXCLK",
1249			activity_monitor.Gfx_FPS,
1250			activity_monitor.Gfx_MinFreqStep,
1251			activity_monitor.Gfx_MinActiveFreqType,
1252			activity_monitor.Gfx_MinActiveFreq,
1253			activity_monitor.Gfx_BoosterFreqType,
1254			activity_monitor.Gfx_BoosterFreq,
1255			activity_monitor.Gfx_PD_Data_limit_c,
1256			activity_monitor.Gfx_PD_Data_error_coeff,
1257			activity_monitor.Gfx_PD_Data_error_rate_coeff);
1258
1259		size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1260			" ",
1261			1,
1262			"SOCCLK",
1263			activity_monitor.Fclk_FPS,
1264			activity_monitor.Fclk_MinFreqStep,
1265			activity_monitor.Fclk_MinActiveFreqType,
1266			activity_monitor.Fclk_MinActiveFreq,
1267			activity_monitor.Fclk_BoosterFreqType,
1268			activity_monitor.Fclk_BoosterFreq,
1269			activity_monitor.Fclk_PD_Data_limit_c,
1270			activity_monitor.Fclk_PD_Data_error_coeff,
1271			activity_monitor.Fclk_PD_Data_error_rate_coeff);
1272
1273		size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1274			" ",
1275			2,
1276			"MEMLK",
1277			activity_monitor.Mem_FPS,
1278			activity_monitor.Mem_MinFreqStep,
1279			activity_monitor.Mem_MinActiveFreqType,
1280			activity_monitor.Mem_MinActiveFreq,
1281			activity_monitor.Mem_BoosterFreqType,
1282			activity_monitor.Mem_BoosterFreq,
1283			activity_monitor.Mem_PD_Data_limit_c,
1284			activity_monitor.Mem_PD_Data_error_coeff,
1285			activity_monitor.Mem_PD_Data_error_rate_coeff);
1286	}
1287
1288	return size;
1289}
1290
1291static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
1292{
1293	DpmActivityMonitorCoeffInt_t activity_monitor;
1294	int workload_type, ret = 0;
1295
1296	smu->power_profile_mode = input[size];
1297
1298	if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
1299		dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);
1300		return -EINVAL;
1301	}
1302
1303	if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
1304
1305		ret = smu_cmn_update_table(smu,
1306				       SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
1307				       (void *)(&activity_monitor), false);
1308		if (ret) {
1309			dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1310			return ret;
1311		}
1312
1313		switch (input[0]) {
1314		case 0: /* Gfxclk */
1315			activity_monitor.Gfx_FPS = input[1];
1316			activity_monitor.Gfx_MinFreqStep = input[2];
1317			activity_monitor.Gfx_MinActiveFreqType = input[3];
1318			activity_monitor.Gfx_MinActiveFreq = input[4];
1319			activity_monitor.Gfx_BoosterFreqType = input[5];
1320			activity_monitor.Gfx_BoosterFreq = input[6];
1321			activity_monitor.Gfx_PD_Data_limit_c = input[7];
1322			activity_monitor.Gfx_PD_Data_error_coeff = input[8];
1323			activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9];
1324			break;
1325		case 1: /* Socclk */
1326			activity_monitor.Fclk_FPS = input[1];
1327			activity_monitor.Fclk_MinFreqStep = input[2];
1328			activity_monitor.Fclk_MinActiveFreqType = input[3];
1329			activity_monitor.Fclk_MinActiveFreq = input[4];
1330			activity_monitor.Fclk_BoosterFreqType = input[5];
1331			activity_monitor.Fclk_BoosterFreq = input[6];
1332			activity_monitor.Fclk_PD_Data_limit_c = input[7];
1333			activity_monitor.Fclk_PD_Data_error_coeff = input[8];
1334			activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9];
1335			break;
1336		case 2: /* Memlk */
1337			activity_monitor.Mem_FPS = input[1];
1338			activity_monitor.Mem_MinFreqStep = input[2];
1339			activity_monitor.Mem_MinActiveFreqType = input[3];
1340			activity_monitor.Mem_MinActiveFreq = input[4];
1341			activity_monitor.Mem_BoosterFreqType = input[5];
1342			activity_monitor.Mem_BoosterFreq = input[6];
1343			activity_monitor.Mem_PD_Data_limit_c = input[7];
1344			activity_monitor.Mem_PD_Data_error_coeff = input[8];
1345			activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
1346			break;
1347		}
1348
1349		ret = smu_cmn_update_table(smu,
1350				       SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
1351				       (void *)(&activity_monitor), true);
1352		if (ret) {
1353			dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
1354			return ret;
1355		}
1356	}
1357
1358	/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1359	workload_type = smu_cmn_to_asic_specific_index(smu,
1360						       CMN2ASIC_MAPPING_WORKLOAD,
1361						       smu->power_profile_mode);
1362	if (workload_type < 0)
1363		return -EINVAL;
1364	smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1365				    1 << workload_type, NULL);
1366
1367	return ret;
1368}
1369
1370static int sienna_cichlid_notify_smc_display_config(struct smu_context *smu)
1371{
1372	struct smu_clocks min_clocks = {0};
1373	struct pp_display_clock_request clock_req;
1374	int ret = 0;
1375
1376	min_clocks.dcef_clock = smu->display_config->min_dcef_set_clk;
1377	min_clocks.dcef_clock_in_sr = smu->display_config->min_dcef_deep_sleep_set_clk;
1378	min_clocks.memory_clock = smu->display_config->min_mem_set_clock;
1379
1380	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
1381		clock_req.clock_type = amd_pp_dcef_clock;
1382		clock_req.clock_freq_in_khz = min_clocks.dcef_clock * 10;
1383
1384		ret = smu_v11_0_display_clock_voltage_request(smu, &clock_req);
1385		if (!ret) {
1386			if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_DCEFCLK_BIT)) {
1387				ret = smu_cmn_send_smc_msg_with_param(smu,
1388								  SMU_MSG_SetMinDeepSleepDcefclk,
1389								  min_clocks.dcef_clock_in_sr/100,
1390								  NULL);
1391				if (ret) {
1392					dev_err(smu->adev->dev, "Attempt to set divider for DCEFCLK Failed!");
1393					return ret;
1394				}
1395			}
1396		} else {
1397			dev_info(smu->adev->dev, "Attempt to set Hard Min for DCEFCLK Failed!");
1398		}
1399	}
1400
1401	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
1402		ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_clocks.memory_clock/100, 0);
1403		if (ret) {
1404			dev_err(smu->adev->dev, "[%s] Set hard min uclk failed!", __func__);
1405			return ret;
1406		}
1407	}
1408
1409	return 0;
1410}
1411
1412static int sienna_cichlid_set_watermarks_table(struct smu_context *smu,
1413					       struct dm_pp_wm_sets_with_clock_ranges_soc15
1414					       *clock_ranges)
1415{
1416	Watermarks_t *table = smu->smu_table.watermarks_table;
1417	int ret = 0;
1418	int i;
1419
1420	if (clock_ranges) {
1421		if (clock_ranges->num_wm_dmif_sets > 4 ||
1422		    clock_ranges->num_wm_mcif_sets > 4)
1423			return -EINVAL;
1424
1425		for (i = 0; i < clock_ranges->num_wm_dmif_sets; i++) {
1426			table->WatermarkRow[1][i].MinClock =
1427				cpu_to_le16((uint16_t)
1428				(clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz /
1429				1000));
1430			table->WatermarkRow[1][i].MaxClock =
1431				cpu_to_le16((uint16_t)
1432				(clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz /
1433				1000));
1434			table->WatermarkRow[1][i].MinUclk =
1435				cpu_to_le16((uint16_t)
1436				(clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz /
1437				1000));
1438			table->WatermarkRow[1][i].MaxUclk =
1439				cpu_to_le16((uint16_t)
1440				(clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz /
1441				1000));
1442			table->WatermarkRow[1][i].WmSetting = (uint8_t)
1443					clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
1444		}
1445
1446		for (i = 0; i < clock_ranges->num_wm_mcif_sets; i++) {
1447			table->WatermarkRow[0][i].MinClock =
1448				cpu_to_le16((uint16_t)
1449				(clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz /
1450				1000));
1451			table->WatermarkRow[0][i].MaxClock =
1452				cpu_to_le16((uint16_t)
1453				(clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz /
1454				1000));
1455			table->WatermarkRow[0][i].MinUclk =
1456				cpu_to_le16((uint16_t)
1457				(clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz /
1458				1000));
1459			table->WatermarkRow[0][i].MaxUclk =
1460				cpu_to_le16((uint16_t)
1461				(clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz /
1462				1000));
1463			table->WatermarkRow[0][i].WmSetting = (uint8_t)
1464					clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
1465		}
1466
1467		smu->watermarks_bitmap |= WATERMARKS_EXIST;
1468	}
1469
1470	if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
1471	     !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
1472		ret = smu_cmn_write_watermarks_table(smu);
1473		if (ret) {
1474			dev_err(smu->adev->dev, "Failed to update WMTABLE!");
1475			return ret;
1476		}
1477		smu->watermarks_bitmap |= WATERMARKS_LOADED;
1478	}
1479
1480	return 0;
1481}
1482
1483static int sienna_cichlid_thermal_get_temperature(struct smu_context *smu,
1484					     enum amd_pp_sensors sensor,
1485					     uint32_t *value)
1486{
1487	int ret = 0;
1488
1489	if (!value)
1490		return -EINVAL;
1491
1492	switch (sensor) {
1493	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1494		ret = sienna_cichlid_get_smu_metrics_data(smu,
1495							  METRICS_TEMPERATURE_HOTSPOT,
1496							  value);
1497		break;
1498	case AMDGPU_PP_SENSOR_EDGE_TEMP:
1499		ret = sienna_cichlid_get_smu_metrics_data(smu,
1500							  METRICS_TEMPERATURE_EDGE,
1501							  value);
1502		break;
1503	case AMDGPU_PP_SENSOR_MEM_TEMP:
1504		ret = sienna_cichlid_get_smu_metrics_data(smu,
1505							  METRICS_TEMPERATURE_MEM,
1506							  value);
1507		break;
1508	default:
1509		dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n");
1510		return -EINVAL;
1511	}
1512
1513	return ret;
1514}
1515
1516static int sienna_cichlid_read_sensor(struct smu_context *smu,
1517				 enum amd_pp_sensors sensor,
1518				 void *data, uint32_t *size)
1519{
1520	int ret = 0;
1521	struct smu_table_context *table_context = &smu->smu_table;
1522	PPTable_t *pptable = table_context->driver_pptable;
1523
1524	if(!data || !size)
1525		return -EINVAL;
1526
1527	mutex_lock(&smu->sensor_lock);
1528	switch (sensor) {
1529	case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
1530		*(uint32_t *)data = pptable->FanMaximumRpm;
1531		*size = 4;
1532		break;
1533	case AMDGPU_PP_SENSOR_MEM_LOAD:
1534	case AMDGPU_PP_SENSOR_GPU_LOAD:
1535		ret = sienna_cichlid_get_current_activity_percent(smu, sensor, (uint32_t *)data);
1536		*size = 4;
1537		break;
1538	case AMDGPU_PP_SENSOR_GPU_POWER:
1539		ret = sienna_cichlid_get_gpu_power(smu, (uint32_t *)data);
1540		*size = 4;
1541		break;
1542	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1543	case AMDGPU_PP_SENSOR_EDGE_TEMP:
1544	case AMDGPU_PP_SENSOR_MEM_TEMP:
1545		ret = sienna_cichlid_thermal_get_temperature(smu, sensor, (uint32_t *)data);
1546		*size = 4;
1547		break;
1548	case AMDGPU_PP_SENSOR_GFX_MCLK:
1549		ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data);
1550		*(uint32_t *)data *= 100;
1551		*size = 4;
1552		break;
1553	case AMDGPU_PP_SENSOR_GFX_SCLK:
1554		ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data);
1555		*(uint32_t *)data *= 100;
1556		*size = 4;
1557		break;
1558	case AMDGPU_PP_SENSOR_VDDGFX:
1559		ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data);
1560		*size = 4;
1561		break;
1562	default:
1563		ret = -EOPNOTSUPP;
1564		break;
1565	}
1566	mutex_unlock(&smu->sensor_lock);
1567
1568	return ret;
1569}
1570
1571static int sienna_cichlid_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states)
1572{
1573	uint32_t num_discrete_levels = 0;
1574	uint16_t *dpm_levels = NULL;
1575	uint16_t i = 0;
1576	struct smu_table_context *table_context = &smu->smu_table;
1577	PPTable_t *driver_ppt = NULL;
1578
1579	if (!clocks_in_khz || !num_states || !table_context->driver_pptable)
1580		return -EINVAL;
1581
1582	driver_ppt = table_context->driver_pptable;
1583	num_discrete_levels = driver_ppt->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels;
1584	dpm_levels = driver_ppt->FreqTableUclk;
1585
1586	if (num_discrete_levels == 0 || dpm_levels == NULL)
1587		return -EINVAL;
1588
1589	*num_states = num_discrete_levels;
1590	for (i = 0; i < num_discrete_levels; i++) {
1591		/* convert to khz */
1592		*clocks_in_khz = (*dpm_levels) * 1000;
1593		clocks_in_khz++;
1594		dpm_levels++;
1595	}
1596
1597	return 0;
1598}
1599
1600static int sienna_cichlid_get_thermal_temperature_range(struct smu_context *smu,
1601						struct smu_temperature_range *range)
1602{
1603	struct smu_table_context *table_context = &smu->smu_table;
1604	struct smu_11_0_7_powerplay_table *powerplay_table =
1605				table_context->power_play_table;
1606	PPTable_t *pptable = smu->smu_table.driver_pptable;
1607
1608	if (!range)
1609		return -EINVAL;
1610
1611	memcpy(range, &smu11_thermal_policy[0], sizeof(struct smu_temperature_range));
1612
1613	range->max = pptable->TemperatureLimit[TEMP_EDGE] *
1614		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1615	range->edge_emergency_max = (pptable->TemperatureLimit[TEMP_EDGE] + CTF_OFFSET_EDGE) *
1616		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1617	range->hotspot_crit_max = pptable->TemperatureLimit[TEMP_HOTSPOT] *
1618		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1619	range->hotspot_emergency_max = (pptable->TemperatureLimit[TEMP_HOTSPOT] + CTF_OFFSET_HOTSPOT) *
1620		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1621	range->mem_crit_max = pptable->TemperatureLimit[TEMP_MEM] *
1622		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1623	range->mem_emergency_max = (pptable->TemperatureLimit[TEMP_MEM] + CTF_OFFSET_MEM)*
1624		SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1625	range->software_shutdown_temp = powerplay_table->software_shutdown_temp;
1626
1627	return 0;
1628}
1629
1630static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context *smu,
1631						bool disable_memory_clock_switch)
1632{
1633	int ret = 0;
1634	struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks =
1635		(struct smu_11_0_max_sustainable_clocks *)
1636			smu->smu_table.max_sustainable_clocks;
1637	uint32_t min_memory_clock = smu->hard_min_uclk_req_from_dal;
1638	uint32_t max_memory_clock = max_sustainable_clocks->uclock;
1639
1640	if(smu->disable_uclk_switch == disable_memory_clock_switch)
1641		return 0;
1642
1643	if(disable_memory_clock_switch)
1644		ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, max_memory_clock, 0);
1645	else
1646		ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_memory_clock, 0);
1647
1648	if(!ret)
1649		smu->disable_uclk_switch = disable_memory_clock_switch;
1650
1651	return ret;
1652}
1653
1654static int sienna_cichlid_get_power_limit(struct smu_context *smu)
1655{
1656	struct smu_11_0_7_powerplay_table *powerplay_table =
1657		(struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table;
1658	PPTable_t *pptable = smu->smu_table.driver_pptable;
1659	uint32_t power_limit, od_percent;
1660
1661	if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
1662		/* the last hope to figure out the ppt limit */
1663		if (!pptable) {
1664			dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!");
1665			return -EINVAL;
1666		}
1667		power_limit =
1668			pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
1669	}
1670	smu->current_power_limit = power_limit;
1671
1672	if (smu->od_enabled) {
1673		od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
1674
1675		dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
1676
1677		power_limit *= (100 + od_percent);
1678		power_limit /= 100;
1679	}
1680	smu->max_power_limit = power_limit;
1681
1682	return 0;
1683}
1684
1685static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
1686					 uint32_t pcie_gen_cap,
1687					 uint32_t pcie_width_cap)
1688{
1689	struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
1690	PPTable_t *pptable = smu->smu_table.driver_pptable;
1691	uint32_t smu_pcie_arg;
1692	int ret, i;
1693
1694	/* lclk dpm table setup */
1695	for (i = 0; i < MAX_PCIE_CONF; i++) {
1696		dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pptable->PcieGenSpeed[i];
1697		dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pptable->PcieLaneCount[i];
1698	}
1699
1700	for (i = 0; i < NUM_LINK_LEVELS; i++) {
1701		smu_pcie_arg = (i << 16) |
1702			((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ?
1703					(pptable->PcieGenSpeed[i] << 8) :
1704					(pcie_gen_cap << 8)) |
1705			((pptable->PcieLaneCount[i] <= pcie_width_cap) ?
1706					pptable->PcieLaneCount[i] :
1707					pcie_width_cap);
1708
1709		ret = smu_cmn_send_smc_msg_with_param(smu,
1710					  SMU_MSG_OverridePcieParameters,
1711					  smu_pcie_arg,
1712					  NULL);
1713
1714		if (ret)
1715			return ret;
1716
1717		if (pptable->PcieGenSpeed[i] > pcie_gen_cap)
1718			dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pcie_gen_cap;
1719		if (pptable->PcieLaneCount[i] > pcie_width_cap)
1720			dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pcie_width_cap;
1721	}
1722
1723	return 0;
1724}
1725
1726static int sienna_cichlid_get_dpm_ultimate_freq(struct smu_context *smu,
1727				enum smu_clk_type clk_type,
1728				uint32_t *min, uint32_t *max)
1729{
1730	struct amdgpu_device *adev = smu->adev;
1731	int ret;
1732
1733	if (clk_type == SMU_GFXCLK)
1734		amdgpu_gfx_off_ctrl(adev, false);
1735	ret = smu_v11_0_get_dpm_ultimate_freq(smu, clk_type, min, max);
1736	if (clk_type == SMU_GFXCLK)
1737		amdgpu_gfx_off_ctrl(adev, true);
1738
1739	return ret;
1740}
1741
1742static int sienna_cichlid_run_btc(struct smu_context *smu)
1743{
1744	return smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
1745}
1746
1747static bool sienna_cichlid_is_baco_supported(struct smu_context *smu)
1748{
1749	struct amdgpu_device *adev = smu->adev;
1750	uint32_t val;
1751
1752	if (amdgpu_sriov_vf(adev) || (!smu_v11_0_baco_is_support(smu)))
1753		return false;
1754
1755	val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
1756	return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false;
1757}
1758
1759static bool sienna_cichlid_is_mode1_reset_supported(struct smu_context *smu)
1760{
1761	struct amdgpu_device *adev = smu->adev;
1762	uint32_t val;
1763	u32 smu_version;
1764
1765	/**
1766	 * SRIOV env will not support SMU mode1 reset
1767	 * PM FW support mode1 reset from 58.26
1768	 */
1769	smu_cmn_get_smc_version(smu, NULL, &smu_version);
1770	if (amdgpu_sriov_vf(adev) || (smu_version < 0x003a1a00))
1771		return false;
1772
1773	/**
1774	 * mode1 reset relies on PSP, so we should check if
1775	 * PSP is alive.
1776	 */
1777	val = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
1778	return val != 0x0;
1779}
1780
1781static void sienna_cichlid_dump_pptable(struct smu_context *smu)
1782{
1783	struct smu_table_context *table_context = &smu->smu_table;
1784	PPTable_t *pptable = table_context->driver_pptable;
1785	int i;
1786
1787	dev_info(smu->adev->dev, "Dumped PPTable:\n");
1788
1789	dev_info(smu->adev->dev, "Version = 0x%08x\n", pptable->Version);
1790	dev_info(smu->adev->dev, "FeaturesToRun[0] = 0x%08x\n", pptable->FeaturesToRun[0]);
1791	dev_info(smu->adev->dev, "FeaturesToRun[1] = 0x%08x\n", pptable->FeaturesToRun[1]);
1792
1793	for (i = 0; i < PPT_THROTTLER_COUNT; i++) {
1794		dev_info(smu->adev->dev, "SocketPowerLimitAc[%d] = 0x%x\n", i, pptable->SocketPowerLimitAc[i]);
1795		dev_info(smu->adev->dev, "SocketPowerLimitAcTau[%d] = 0x%x\n", i, pptable->SocketPowerLimitAcTau[i]);
1796		dev_info(smu->adev->dev, "SocketPowerLimitDc[%d] = 0x%x\n", i, pptable->SocketPowerLimitDc[i]);
1797		dev_info(smu->adev->dev, "SocketPowerLimitDcTau[%d] = 0x%x\n", i, pptable->SocketPowerLimitDcTau[i]);
1798	}
1799
1800	for (i = 0; i < TDC_THROTTLER_COUNT; i++) {
1801		dev_info(smu->adev->dev, "TdcLimit[%d] = 0x%x\n", i, pptable->TdcLimit[i]);
1802		dev_info(smu->adev->dev, "TdcLimitTau[%d] = 0x%x\n", i, pptable->TdcLimitTau[i]);
1803	}
1804
1805	for (i = 0; i < TEMP_COUNT; i++) {
1806		dev_info(smu->adev->dev, "TemperatureLimit[%d] = 0x%x\n", i, pptable->TemperatureLimit[i]);
1807	}
1808
1809	dev_info(smu->adev->dev, "FitLimit = 0x%x\n", pptable->FitLimit);
1810	dev_info(smu->adev->dev, "TotalPowerConfig = 0x%x\n", pptable->TotalPowerConfig);
1811	dev_info(smu->adev->dev, "TotalPowerPadding[0] = 0x%x\n", pptable->TotalPowerPadding[0]);
1812	dev_info(smu->adev->dev, "TotalPowerPadding[1] = 0x%x\n", pptable->TotalPowerPadding[1]);
1813	dev_info(smu->adev->dev, "TotalPowerPadding[2] = 0x%x\n", pptable->TotalPowerPadding[2]);
1814
1815	dev_info(smu->adev->dev, "ApccPlusResidencyLimit = 0x%x\n", pptable->ApccPlusResidencyLimit);
1816	for (i = 0; i < NUM_SMNCLK_DPM_LEVELS; i++) {
1817		dev_info(smu->adev->dev, "SmnclkDpmFreq[%d] = 0x%x\n", i, pptable->SmnclkDpmFreq[i]);
1818		dev_info(smu->adev->dev, "SmnclkDpmVoltage[%d] = 0x%x\n", i, pptable->SmnclkDpmVoltage[i]);
1819	}
1820	dev_info(smu->adev->dev, "PaddingAPCC[0] = 0x%x\n", pptable->PaddingAPCC[0]);
1821	dev_info(smu->adev->dev, "PaddingAPCC[1] = 0x%x\n", pptable->PaddingAPCC[1]);
1822	dev_info(smu->adev->dev, "PaddingAPCC[2] = 0x%x\n", pptable->PaddingAPCC[2]);
1823	dev_info(smu->adev->dev, "PaddingAPCC[3] = 0x%x\n", pptable->PaddingAPCC[3]);
1824
1825	dev_info(smu->adev->dev, "ThrottlerControlMask = 0x%x\n", pptable->ThrottlerControlMask);
1826
1827	dev_info(smu->adev->dev, "FwDStateMask = 0x%x\n", pptable->FwDStateMask);
1828
1829	dev_info(smu->adev->dev, "UlvVoltageOffsetSoc = 0x%x\n", pptable->UlvVoltageOffsetSoc);
1830	dev_info(smu->adev->dev, "UlvVoltageOffsetGfx = 0x%x\n", pptable->UlvVoltageOffsetGfx);
1831	dev_info(smu->adev->dev, "MinVoltageUlvGfx = 0x%x\n", pptable->MinVoltageUlvGfx);
1832	dev_info(smu->adev->dev, "MinVoltageUlvSoc = 0x%x\n", pptable->MinVoltageUlvSoc);
1833
1834	dev_info(smu->adev->dev, "SocLIVmin = 0x%x\n", pptable->SocLIVmin);
1835	dev_info(smu->adev->dev, "PaddingLIVmin = 0x%x\n", pptable->PaddingLIVmin);
1836
1837	dev_info(smu->adev->dev, "GceaLinkMgrIdleThreshold = 0x%x\n", pptable->GceaLinkMgrIdleThreshold);
1838	dev_info(smu->adev->dev, "paddingRlcUlvParams[0] = 0x%x\n", pptable->paddingRlcUlvParams[0]);
1839	dev_info(smu->adev->dev, "paddingRlcUlvParams[1] = 0x%x\n", pptable->paddingRlcUlvParams[1]);
1840	dev_info(smu->adev->dev, "paddingRlcUlvParams[2] = 0x%x\n", pptable->paddingRlcUlvParams[2]);
1841
1842	dev_info(smu->adev->dev, "MinVoltageGfx = 0x%x\n", pptable->MinVoltageGfx);
1843	dev_info(smu->adev->dev, "MinVoltageSoc = 0x%x\n", pptable->MinVoltageSoc);
1844	dev_info(smu->adev->dev, "MaxVoltageGfx = 0x%x\n", pptable->MaxVoltageGfx);
1845	dev_info(smu->adev->dev, "MaxVoltageSoc = 0x%x\n", pptable->MaxVoltageSoc);
1846
1847	dev_info(smu->adev->dev, "LoadLineResistanceGfx = 0x%x\n", pptable->LoadLineResistanceGfx);
1848	dev_info(smu->adev->dev, "LoadLineResistanceSoc = 0x%x\n", pptable->LoadLineResistanceSoc);
1849
1850	dev_info(smu->adev->dev, "VDDGFX_TVmin = 0x%x\n", pptable->VDDGFX_TVmin);
1851	dev_info(smu->adev->dev, "VDDSOC_TVmin = 0x%x\n", pptable->VDDSOC_TVmin);
1852	dev_info(smu->adev->dev, "VDDGFX_Vmin_HiTemp = 0x%x\n", pptable->VDDGFX_Vmin_HiTemp);
1853	dev_info(smu->adev->dev, "VDDGFX_Vmin_LoTemp = 0x%x\n", pptable->VDDGFX_Vmin_LoTemp);
1854	dev_info(smu->adev->dev, "VDDSOC_Vmin_HiTemp = 0x%x\n", pptable->VDDSOC_Vmin_HiTemp);
1855	dev_info(smu->adev->dev, "VDDSOC_Vmin_LoTemp = 0x%x\n", pptable->VDDSOC_Vmin_LoTemp);
1856	dev_info(smu->adev->dev, "VDDGFX_TVminHystersis = 0x%x\n", pptable->VDDGFX_TVminHystersis);
1857	dev_info(smu->adev->dev, "VDDSOC_TVminHystersis = 0x%x\n", pptable->VDDSOC_TVminHystersis);
1858
1859	dev_info(smu->adev->dev, "[PPCLK_GFXCLK]\n"
1860			"  .VoltageMode          = 0x%02x\n"
1861			"  .SnapToDiscrete       = 0x%02x\n"
1862			"  .NumDiscreteLevels    = 0x%02x\n"
1863			"  .padding              = 0x%02x\n"
1864			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1865			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1866			"  .SsFmin               = 0x%04x\n"
1867			"  .Padding_16           = 0x%04x\n",
1868			pptable->DpmDescriptor[PPCLK_GFXCLK].VoltageMode,
1869			pptable->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete,
1870			pptable->DpmDescriptor[PPCLK_GFXCLK].NumDiscreteLevels,
1871			pptable->DpmDescriptor[PPCLK_GFXCLK].Padding,
1872			pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.m,
1873			pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.b,
1874			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.a,
1875			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.b,
1876			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.c,
1877			pptable->DpmDescriptor[PPCLK_GFXCLK].SsFmin,
1878			pptable->DpmDescriptor[PPCLK_GFXCLK].Padding16);
1879
1880	dev_info(smu->adev->dev, "[PPCLK_SOCCLK]\n"
1881			"  .VoltageMode          = 0x%02x\n"
1882			"  .SnapToDiscrete       = 0x%02x\n"
1883			"  .NumDiscreteLevels    = 0x%02x\n"
1884			"  .padding              = 0x%02x\n"
1885			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1886			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1887			"  .SsFmin               = 0x%04x\n"
1888			"  .Padding_16           = 0x%04x\n",
1889			pptable->DpmDescriptor[PPCLK_SOCCLK].VoltageMode,
1890			pptable->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete,
1891			pptable->DpmDescriptor[PPCLK_SOCCLK].NumDiscreteLevels,
1892			pptable->DpmDescriptor[PPCLK_SOCCLK].Padding,
1893			pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.m,
1894			pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.b,
1895			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.a,
1896			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.b,
1897			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.c,
1898			pptable->DpmDescriptor[PPCLK_SOCCLK].SsFmin,
1899			pptable->DpmDescriptor[PPCLK_SOCCLK].Padding16);
1900
1901	dev_info(smu->adev->dev, "[PPCLK_UCLK]\n"
1902			"  .VoltageMode          = 0x%02x\n"
1903			"  .SnapToDiscrete       = 0x%02x\n"
1904			"  .NumDiscreteLevels    = 0x%02x\n"
1905			"  .padding              = 0x%02x\n"
1906			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1907			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1908			"  .SsFmin               = 0x%04x\n"
1909			"  .Padding_16           = 0x%04x\n",
1910			pptable->DpmDescriptor[PPCLK_UCLK].VoltageMode,
1911			pptable->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete,
1912			pptable->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels,
1913			pptable->DpmDescriptor[PPCLK_UCLK].Padding,
1914			pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.m,
1915			pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.b,
1916			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.a,
1917			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.b,
1918			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.c,
1919			pptable->DpmDescriptor[PPCLK_UCLK].SsFmin,
1920			pptable->DpmDescriptor[PPCLK_UCLK].Padding16);
1921
1922	dev_info(smu->adev->dev, "[PPCLK_FCLK]\n"
1923			"  .VoltageMode          = 0x%02x\n"
1924			"  .SnapToDiscrete       = 0x%02x\n"
1925			"  .NumDiscreteLevels    = 0x%02x\n"
1926			"  .padding              = 0x%02x\n"
1927			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1928			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1929			"  .SsFmin               = 0x%04x\n"
1930			"  .Padding_16           = 0x%04x\n",
1931			pptable->DpmDescriptor[PPCLK_FCLK].VoltageMode,
1932			pptable->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete,
1933			pptable->DpmDescriptor[PPCLK_FCLK].NumDiscreteLevels,
1934			pptable->DpmDescriptor[PPCLK_FCLK].Padding,
1935			pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.m,
1936			pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.b,
1937			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.a,
1938			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.b,
1939			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.c,
1940			pptable->DpmDescriptor[PPCLK_FCLK].SsFmin,
1941			pptable->DpmDescriptor[PPCLK_FCLK].Padding16);
1942
1943	dev_info(smu->adev->dev, "[PPCLK_DCLK_0]\n"
1944			"  .VoltageMode          = 0x%02x\n"
1945			"  .SnapToDiscrete       = 0x%02x\n"
1946			"  .NumDiscreteLevels    = 0x%02x\n"
1947			"  .padding              = 0x%02x\n"
1948			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1949			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1950			"  .SsFmin               = 0x%04x\n"
1951			"  .Padding_16           = 0x%04x\n",
1952			pptable->DpmDescriptor[PPCLK_DCLK_0].VoltageMode,
1953			pptable->DpmDescriptor[PPCLK_DCLK_0].SnapToDiscrete,
1954			pptable->DpmDescriptor[PPCLK_DCLK_0].NumDiscreteLevels,
1955			pptable->DpmDescriptor[PPCLK_DCLK_0].Padding,
1956			pptable->DpmDescriptor[PPCLK_DCLK_0].ConversionToAvfsClk.m,
1957			pptable->DpmDescriptor[PPCLK_DCLK_0].ConversionToAvfsClk.b,
1958			pptable->DpmDescriptor[PPCLK_DCLK_0].SsCurve.a,
1959			pptable->DpmDescriptor[PPCLK_DCLK_0].SsCurve.b,
1960			pptable->DpmDescriptor[PPCLK_DCLK_0].SsCurve.c,
1961			pptable->DpmDescriptor[PPCLK_DCLK_0].SsFmin,
1962			pptable->DpmDescriptor[PPCLK_DCLK_0].Padding16);
1963
1964	dev_info(smu->adev->dev, "[PPCLK_VCLK_0]\n"
1965			"  .VoltageMode          = 0x%02x\n"
1966			"  .SnapToDiscrete       = 0x%02x\n"
1967			"  .NumDiscreteLevels    = 0x%02x\n"
1968			"  .padding              = 0x%02x\n"
1969			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1970			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1971			"  .SsFmin               = 0x%04x\n"
1972			"  .Padding_16           = 0x%04x\n",
1973			pptable->DpmDescriptor[PPCLK_VCLK_0].VoltageMode,
1974			pptable->DpmDescriptor[PPCLK_VCLK_0].SnapToDiscrete,
1975			pptable->DpmDescriptor[PPCLK_VCLK_0].NumDiscreteLevels,
1976			pptable->DpmDescriptor[PPCLK_VCLK_0].Padding,
1977			pptable->DpmDescriptor[PPCLK_VCLK_0].ConversionToAvfsClk.m,
1978			pptable->DpmDescriptor[PPCLK_VCLK_0].ConversionToAvfsClk.b,
1979			pptable->DpmDescriptor[PPCLK_VCLK_0].SsCurve.a,
1980			pptable->DpmDescriptor[PPCLK_VCLK_0].SsCurve.b,
1981			pptable->DpmDescriptor[PPCLK_VCLK_0].SsCurve.c,
1982			pptable->DpmDescriptor[PPCLK_VCLK_0].SsFmin,
1983			pptable->DpmDescriptor[PPCLK_VCLK_0].Padding16);
1984
1985	dev_info(smu->adev->dev, "[PPCLK_DCLK_1]\n"
1986			"  .VoltageMode          = 0x%02x\n"
1987			"  .SnapToDiscrete       = 0x%02x\n"
1988			"  .NumDiscreteLevels    = 0x%02x\n"
1989			"  .padding              = 0x%02x\n"
1990			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1991			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1992			"  .SsFmin               = 0x%04x\n"
1993			"  .Padding_16           = 0x%04x\n",
1994			pptable->DpmDescriptor[PPCLK_DCLK_1].VoltageMode,
1995			pptable->DpmDescriptor[PPCLK_DCLK_1].SnapToDiscrete,
1996			pptable->DpmDescriptor[PPCLK_DCLK_1].NumDiscreteLevels,
1997			pptable->DpmDescriptor[PPCLK_DCLK_1].Padding,
1998			pptable->DpmDescriptor[PPCLK_DCLK_1].ConversionToAvfsClk.m,
1999			pptable->DpmDescriptor[PPCLK_DCLK_1].ConversionToAvfsClk.b,
2000			pptable->DpmDescriptor[PPCLK_DCLK_1].SsCurve.a,
2001			pptable->DpmDescriptor[PPCLK_DCLK_1].SsCurve.b,
2002			pptable->DpmDescriptor[PPCLK_DCLK_1].SsCurve.c,
2003			pptable->DpmDescriptor[PPCLK_DCLK_1].SsFmin,
2004			pptable->DpmDescriptor[PPCLK_DCLK_1].Padding16);
2005
2006	dev_info(smu->adev->dev, "[PPCLK_VCLK_1]\n"
2007			"  .VoltageMode          = 0x%02x\n"
2008			"  .SnapToDiscrete       = 0x%02x\n"
2009			"  .NumDiscreteLevels    = 0x%02x\n"
2010			"  .padding              = 0x%02x\n"
2011			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2012			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2013			"  .SsFmin               = 0x%04x\n"
2014			"  .Padding_16           = 0x%04x\n",
2015			pptable->DpmDescriptor[PPCLK_VCLK_1].VoltageMode,
2016			pptable->DpmDescriptor[PPCLK_VCLK_1].SnapToDiscrete,
2017			pptable->DpmDescriptor[PPCLK_VCLK_1].NumDiscreteLevels,
2018			pptable->DpmDescriptor[PPCLK_VCLK_1].Padding,
2019			pptable->DpmDescriptor[PPCLK_VCLK_1].ConversionToAvfsClk.m,
2020			pptable->DpmDescriptor[PPCLK_VCLK_1].ConversionToAvfsClk.b,
2021			pptable->DpmDescriptor[PPCLK_VCLK_1].SsCurve.a,
2022			pptable->DpmDescriptor[PPCLK_VCLK_1].SsCurve.b,
2023			pptable->DpmDescriptor[PPCLK_VCLK_1].SsCurve.c,
2024			pptable->DpmDescriptor[PPCLK_VCLK_1].SsFmin,
2025			pptable->DpmDescriptor[PPCLK_VCLK_1].Padding16);
2026
2027	dev_info(smu->adev->dev, "FreqTableGfx\n");
2028	for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++)
2029		dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableGfx[i]);
2030
2031	dev_info(smu->adev->dev, "FreqTableVclk\n");
2032	for (i = 0; i < NUM_VCLK_DPM_LEVELS; i++)
2033		dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableVclk[i]);
2034
2035	dev_info(smu->adev->dev, "FreqTableDclk\n");
2036	for (i = 0; i < NUM_DCLK_DPM_LEVELS; i++)
2037		dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableDclk[i]);
2038
2039	dev_info(smu->adev->dev, "FreqTableSocclk\n");
2040	for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++)
2041		dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableSocclk[i]);
2042
2043	dev_info(smu->adev->dev, "FreqTableUclk\n");
2044	for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2045		dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableUclk[i]);
2046
2047	dev_info(smu->adev->dev, "FreqTableFclk\n");
2048	for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++)
2049		dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableFclk[i]);
2050
2051	dev_info(smu->adev->dev, "Paddingclks[0] = 0x%x\n",  pptable->Paddingclks[0]);
2052	dev_info(smu->adev->dev, "Paddingclks[1] = 0x%x\n",  pptable->Paddingclks[1]);
2053	dev_info(smu->adev->dev, "Paddingclks[2] = 0x%x\n",  pptable->Paddingclks[2]);
2054	dev_info(smu->adev->dev, "Paddingclks[3] = 0x%x\n",  pptable->Paddingclks[3]);
2055	dev_info(smu->adev->dev, "Paddingclks[4] = 0x%x\n",  pptable->Paddingclks[4]);
2056	dev_info(smu->adev->dev, "Paddingclks[5] = 0x%x\n",  pptable->Paddingclks[5]);
2057	dev_info(smu->adev->dev, "Paddingclks[6] = 0x%x\n",  pptable->Paddingclks[6]);
2058	dev_info(smu->adev->dev, "Paddingclks[7] = 0x%x\n",  pptable->Paddingclks[7]);
2059	dev_info(smu->adev->dev, "Paddingclks[8] = 0x%x\n",  pptable->Paddingclks[8]);
2060	dev_info(smu->adev->dev, "Paddingclks[9] = 0x%x\n",  pptable->Paddingclks[9]);
2061	dev_info(smu->adev->dev, "Paddingclks[10] = 0x%x\n", pptable->Paddingclks[10]);
2062	dev_info(smu->adev->dev, "Paddingclks[11] = 0x%x\n", pptable->Paddingclks[11]);
2063	dev_info(smu->adev->dev, "Paddingclks[12] = 0x%x\n", pptable->Paddingclks[12]);
2064	dev_info(smu->adev->dev, "Paddingclks[13] = 0x%x\n", pptable->Paddingclks[13]);
2065	dev_info(smu->adev->dev, "Paddingclks[14] = 0x%x\n", pptable->Paddingclks[14]);
2066	dev_info(smu->adev->dev, "Paddingclks[15] = 0x%x\n", pptable->Paddingclks[15]);
2067
2068	dev_info(smu->adev->dev, "DcModeMaxFreq\n");
2069	dev_info(smu->adev->dev, "  .PPCLK_GFXCLK = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_GFXCLK]);
2070	dev_info(smu->adev->dev, "  .PPCLK_SOCCLK = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_SOCCLK]);
2071	dev_info(smu->adev->dev, "  .PPCLK_UCLK   = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_UCLK]);
2072	dev_info(smu->adev->dev, "  .PPCLK_FCLK   = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_FCLK]);
2073	dev_info(smu->adev->dev, "  .PPCLK_DCLK_0 = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_DCLK_0]);
2074	dev_info(smu->adev->dev, "  .PPCLK_VCLK_0 = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_VCLK_0]);
2075	dev_info(smu->adev->dev, "  .PPCLK_DCLK_1 = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_DCLK_1]);
2076	dev_info(smu->adev->dev, "  .PPCLK_VCLK_1 = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_VCLK_1]);
2077
2078	dev_info(smu->adev->dev, "FreqTableUclkDiv\n");
2079	for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2080		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->FreqTableUclkDiv[i]);
2081
2082	dev_info(smu->adev->dev, "FclkBoostFreq = 0x%x\n", pptable->FclkBoostFreq);
2083	dev_info(smu->adev->dev, "FclkParamPadding = 0x%x\n", pptable->FclkParamPadding);
2084
2085	dev_info(smu->adev->dev, "Mp0clkFreq\n");
2086	for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
2087		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->Mp0clkFreq[i]);
2088
2089	dev_info(smu->adev->dev, "Mp0DpmVoltage\n");
2090	for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
2091		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->Mp0DpmVoltage[i]);
2092
2093	dev_info(smu->adev->dev, "MemVddciVoltage\n");
2094	for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2095		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->MemVddciVoltage[i]);
2096
2097	dev_info(smu->adev->dev, "MemMvddVoltage\n");
2098	for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2099		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->MemMvddVoltage[i]);
2100
2101	dev_info(smu->adev->dev, "GfxclkFgfxoffEntry = 0x%x\n", pptable->GfxclkFgfxoffEntry);
2102	dev_info(smu->adev->dev, "GfxclkFinit = 0x%x\n", pptable->GfxclkFinit);
2103	dev_info(smu->adev->dev, "GfxclkFidle = 0x%x\n", pptable->GfxclkFidle);
2104	dev_info(smu->adev->dev, "GfxclkSource = 0x%x\n", pptable->GfxclkSource);
2105	dev_info(smu->adev->dev, "GfxclkPadding = 0x%x\n", pptable->GfxclkPadding);
2106
2107	dev_info(smu->adev->dev, "GfxGpoSubFeatureMask = 0x%x\n", pptable->GfxGpoSubFeatureMask);
2108
2109	dev_info(smu->adev->dev, "GfxGpoEnabledWorkPolicyMask = 0x%x\n", pptable->GfxGpoEnabledWorkPolicyMask);
2110	dev_info(smu->adev->dev, "GfxGpoDisabledWorkPolicyMask = 0x%x\n", pptable->GfxGpoDisabledWorkPolicyMask);
2111	dev_info(smu->adev->dev, "GfxGpoPadding[0] = 0x%x\n", pptable->GfxGpoPadding[0]);
2112	dev_info(smu->adev->dev, "GfxGpoVotingAllow = 0x%x\n", pptable->GfxGpoVotingAllow);
2113	dev_info(smu->adev->dev, "GfxGpoPadding32[0] = 0x%x\n", pptable->GfxGpoPadding32[0]);
2114	dev_info(smu->adev->dev, "GfxGpoPadding32[1] = 0x%x\n", pptable->GfxGpoPadding32[1]);
2115	dev_info(smu->adev->dev, "GfxGpoPadding32[2] = 0x%x\n", pptable->GfxGpoPadding32[2]);
2116	dev_info(smu->adev->dev, "GfxGpoPadding32[3] = 0x%x\n", pptable->GfxGpoPadding32[3]);
2117	dev_info(smu->adev->dev, "GfxDcsFopt = 0x%x\n", pptable->GfxDcsFopt);
2118	dev_info(smu->adev->dev, "GfxDcsFclkFopt = 0x%x\n", pptable->GfxDcsFclkFopt);
2119	dev_info(smu->adev->dev, "GfxDcsUclkFopt = 0x%x\n", pptable->GfxDcsUclkFopt);
2120
2121	dev_info(smu->adev->dev, "DcsGfxOffVoltage = 0x%x\n", pptable->DcsGfxOffVoltage);
2122	dev_info(smu->adev->dev, "DcsMinGfxOffTime = 0x%x\n", pptable->DcsMinGfxOffTime);
2123	dev_info(smu->adev->dev, "DcsMaxGfxOffTime = 0x%x\n", pptable->DcsMaxGfxOffTime);
2124	dev_info(smu->adev->dev, "DcsMinCreditAccum = 0x%x\n", pptable->DcsMinCreditAccum);
2125	dev_info(smu->adev->dev, "DcsExitHysteresis = 0x%x\n", pptable->DcsExitHysteresis);
2126	dev_info(smu->adev->dev, "DcsTimeout = 0x%x\n", pptable->DcsTimeout);
2127
2128	dev_info(smu->adev->dev, "DcsParamPadding[0] = 0x%x\n", pptable->DcsParamPadding[0]);
2129	dev_info(smu->adev->dev, "DcsParamPadding[1] = 0x%x\n", pptable->DcsParamPadding[1]);
2130	dev_info(smu->adev->dev, "DcsParamPadding[2] = 0x%x\n", pptable->DcsParamPadding[2]);
2131	dev_info(smu->adev->dev, "DcsParamPadding[3] = 0x%x\n", pptable->DcsParamPadding[3]);
2132	dev_info(smu->adev->dev, "DcsParamPadding[4] = 0x%x\n", pptable->DcsParamPadding[4]);
2133
2134	dev_info(smu->adev->dev, "FlopsPerByteTable\n");
2135	for (i = 0; i < RLC_PACE_TABLE_NUM_LEVELS; i++)
2136		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->FlopsPerByteTable[i]);
2137
2138	dev_info(smu->adev->dev, "LowestUclkReservedForUlv = 0x%x\n", pptable->LowestUclkReservedForUlv);
2139	dev_info(smu->adev->dev, "vddingMem[0] = 0x%x\n", pptable->PaddingMem[0]);
2140	dev_info(smu->adev->dev, "vddingMem[1] = 0x%x\n", pptable->PaddingMem[1]);
2141	dev_info(smu->adev->dev, "vddingMem[2] = 0x%x\n", pptable->PaddingMem[2]);
2142
2143	dev_info(smu->adev->dev, "UclkDpmPstates\n");
2144	for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2145		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->UclkDpmPstates[i]);
2146
2147	dev_info(smu->adev->dev, "UclkDpmSrcFreqRange\n");
2148	dev_info(smu->adev->dev, "  .Fmin = 0x%x\n",
2149		pptable->UclkDpmSrcFreqRange.Fmin);
2150	dev_info(smu->adev->dev, "  .Fmax = 0x%x\n",
2151		pptable->UclkDpmSrcFreqRange.Fmax);
2152	dev_info(smu->adev->dev, "UclkDpmTargFreqRange\n");
2153	dev_info(smu->adev->dev, "  .Fmin = 0x%x\n",
2154		pptable->UclkDpmTargFreqRange.Fmin);
2155	dev_info(smu->adev->dev, "  .Fmax = 0x%x\n",
2156		pptable->UclkDpmTargFreqRange.Fmax);
2157	dev_info(smu->adev->dev, "UclkDpmMidstepFreq = 0x%x\n", pptable->UclkDpmMidstepFreq);
2158	dev_info(smu->adev->dev, "UclkMidstepPadding = 0x%x\n", pptable->UclkMidstepPadding);
2159
2160	dev_info(smu->adev->dev, "PcieGenSpeed\n");
2161	for (i = 0; i < NUM_LINK_LEVELS; i++)
2162		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->PcieGenSpeed[i]);
2163
2164	dev_info(smu->adev->dev, "PcieLaneCount\n");
2165	for (i = 0; i < NUM_LINK_LEVELS; i++)
2166		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->PcieLaneCount[i]);
2167
2168	dev_info(smu->adev->dev, "LclkFreq\n");
2169	for (i = 0; i < NUM_LINK_LEVELS; i++)
2170		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->LclkFreq[i]);
2171
2172	dev_info(smu->adev->dev, "FanStopTemp = 0x%x\n", pptable->FanStopTemp);
2173	dev_info(smu->adev->dev, "FanStartTemp = 0x%x\n", pptable->FanStartTemp);
2174
2175	dev_info(smu->adev->dev, "FanGain\n");
2176	for (i = 0; i < TEMP_COUNT; i++)
2177		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->FanGain[i]);
2178
2179	dev_info(smu->adev->dev, "FanPwmMin = 0x%x\n", pptable->FanPwmMin);
2180	dev_info(smu->adev->dev, "FanAcousticLimitRpm = 0x%x\n", pptable->FanAcousticLimitRpm);
2181	dev_info(smu->adev->dev, "FanThrottlingRpm = 0x%x\n", pptable->FanThrottlingRpm);
2182	dev_info(smu->adev->dev, "FanMaximumRpm = 0x%x\n", pptable->FanMaximumRpm);
2183	dev_info(smu->adev->dev, "MGpuFanBoostLimitRpm = 0x%x\n", pptable->MGpuFanBoostLimitRpm);
2184	dev_info(smu->adev->dev, "FanTargetTemperature = 0x%x\n", pptable->FanTargetTemperature);
2185	dev_info(smu->adev->dev, "FanTargetGfxclk = 0x%x\n", pptable->FanTargetGfxclk);
2186	dev_info(smu->adev->dev, "FanPadding16 = 0x%x\n", pptable->FanPadding16);
2187	dev_info(smu->adev->dev, "FanTempInputSelect = 0x%x\n", pptable->FanTempInputSelect);
2188	dev_info(smu->adev->dev, "FanPadding = 0x%x\n", pptable->FanPadding);
2189	dev_info(smu->adev->dev, "FanZeroRpmEnable = 0x%x\n", pptable->FanZeroRpmEnable);
2190	dev_info(smu->adev->dev, "FanTachEdgePerRev = 0x%x\n", pptable->FanTachEdgePerRev);
2191
2192	dev_info(smu->adev->dev, "FuzzyFan_ErrorSetDelta = 0x%x\n", pptable->FuzzyFan_ErrorSetDelta);
2193	dev_info(smu->adev->dev, "FuzzyFan_ErrorRateSetDelta = 0x%x\n", pptable->FuzzyFan_ErrorRateSetDelta);
2194	dev_info(smu->adev->dev, "FuzzyFan_PwmSetDelta = 0x%x\n", pptable->FuzzyFan_PwmSetDelta);
2195	dev_info(smu->adev->dev, "FuzzyFan_Reserved = 0x%x\n", pptable->FuzzyFan_Reserved);
2196
2197	dev_info(smu->adev->dev, "OverrideAvfsGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_GFX]);
2198	dev_info(smu->adev->dev, "OverrideAvfsGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_SOC]);
2199	dev_info(smu->adev->dev, "dBtcGbGfxDfllModelSelect = 0x%x\n", pptable->dBtcGbGfxDfllModelSelect);
2200	dev_info(smu->adev->dev, "Padding8_Avfs = 0x%x\n", pptable->Padding8_Avfs);
2201
2202	dev_info(smu->adev->dev, "qAvfsGb[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
2203			pptable->qAvfsGb[AVFS_VOLTAGE_GFX].a,
2204			pptable->qAvfsGb[AVFS_VOLTAGE_GFX].b,
2205			pptable->qAvfsGb[AVFS_VOLTAGE_GFX].c);
2206	dev_info(smu->adev->dev, "qAvfsGb[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
2207			pptable->qAvfsGb[AVFS_VOLTAGE_SOC].a,
2208			pptable->qAvfsGb[AVFS_VOLTAGE_SOC].b,
2209			pptable->qAvfsGb[AVFS_VOLTAGE_SOC].c);
2210	dev_info(smu->adev->dev, "dBtcGbGfxPll{a = 0x%x b = 0x%x c = 0x%x}\n",
2211			pptable->dBtcGbGfxPll.a,
2212			pptable->dBtcGbGfxPll.b,
2213			pptable->dBtcGbGfxPll.c);
2214	dev_info(smu->adev->dev, "dBtcGbGfxAfll{a = 0x%x b = 0x%x c = 0x%x}\n",
2215			pptable->dBtcGbGfxDfll.a,
2216			pptable->dBtcGbGfxDfll.b,
2217			pptable->dBtcGbGfxDfll.c);
2218	dev_info(smu->adev->dev, "dBtcGbSoc{a = 0x%x b = 0x%x c = 0x%x}\n",
2219			pptable->dBtcGbSoc.a,
2220			pptable->dBtcGbSoc.b,
2221			pptable->dBtcGbSoc.c);
2222	dev_info(smu->adev->dev, "qAgingGb[AVFS_VOLTAGE_GFX]{m = 0x%x b = 0x%x}\n",
2223			pptable->qAgingGb[AVFS_VOLTAGE_GFX].m,
2224			pptable->qAgingGb[AVFS_VOLTAGE_GFX].b);
2225	dev_info(smu->adev->dev, "qAgingGb[AVFS_VOLTAGE_SOC]{m = 0x%x b = 0x%x}\n",
2226			pptable->qAgingGb[AVFS_VOLTAGE_SOC].m,
2227			pptable->qAgingGb[AVFS_VOLTAGE_SOC].b);
2228
2229	dev_info(smu->adev->dev, "PiecewiseLinearDroopIntGfxDfll\n");
2230	for (i = 0; i < NUM_PIECE_WISE_LINEAR_DROOP_MODEL_VF_POINTS; i++) {
2231		dev_info(smu->adev->dev, "		Fset[%d] = 0x%x\n",
2232			i, pptable->PiecewiseLinearDroopIntGfxDfll.Fset[i]);
2233		dev_info(smu->adev->dev, "		Vdroop[%d] = 0x%x\n",
2234			i, pptable->PiecewiseLinearDroopIntGfxDfll.Vdroop[i]);
2235	}
2236
2237	dev_info(smu->adev->dev, "qStaticVoltageOffset[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
2238			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].a,
2239			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].b,
2240			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].c);
2241	dev_info(smu->adev->dev, "qStaticVoltageOffset[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
2242			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].a,
2243			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].b,
2244			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].c);
2245
2246	dev_info(smu->adev->dev, "DcTol[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_GFX]);
2247	dev_info(smu->adev->dev, "DcTol[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_SOC]);
2248
2249	dev_info(smu->adev->dev, "DcBtcEnabled[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_GFX]);
2250	dev_info(smu->adev->dev, "DcBtcEnabled[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_SOC]);
2251	dev_info(smu->adev->dev, "Padding8_GfxBtc[0] = 0x%x\n", pptable->Padding8_GfxBtc[0]);
2252	dev_info(smu->adev->dev, "Padding8_GfxBtc[1] = 0x%x\n", pptable->Padding8_GfxBtc[1]);
2253
2254	dev_info(smu->adev->dev, "DcBtcMin[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_GFX]);
2255	dev_info(smu->adev->dev, "DcBtcMin[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_SOC]);
2256	dev_info(smu->adev->dev, "DcBtcMax[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_GFX]);
2257	dev_info(smu->adev->dev, "DcBtcMax[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_SOC]);
2258
2259	dev_info(smu->adev->dev, "DcBtcGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_GFX]);
2260	dev_info(smu->adev->dev, "DcBtcGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_SOC]);
2261
2262	dev_info(smu->adev->dev, "XgmiDpmPstates\n");
2263	for (i = 0; i < NUM_XGMI_LEVELS; i++)
2264		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiDpmPstates[i]);
2265	dev_info(smu->adev->dev, "XgmiDpmSpare[0] = 0x%02x\n", pptable->XgmiDpmSpare[0]);
2266	dev_info(smu->adev->dev, "XgmiDpmSpare[1] = 0x%02x\n", pptable->XgmiDpmSpare[1]);
2267
2268	dev_info(smu->adev->dev, "DebugOverrides = 0x%x\n", pptable->DebugOverrides);
2269	dev_info(smu->adev->dev, "ReservedEquation0{a = 0x%x b = 0x%x c = 0x%x}\n",
2270			pptable->ReservedEquation0.a,
2271			pptable->ReservedEquation0.b,
2272			pptable->ReservedEquation0.c);
2273	dev_info(smu->adev->dev, "ReservedEquation1{a = 0x%x b = 0x%x c = 0x%x}\n",
2274			pptable->ReservedEquation1.a,
2275			pptable->ReservedEquation1.b,
2276			pptable->ReservedEquation1.c);
2277	dev_info(smu->adev->dev, "ReservedEquation2{a = 0x%x b = 0x%x c = 0x%x}\n",
2278			pptable->ReservedEquation2.a,
2279			pptable->ReservedEquation2.b,
2280			pptable->ReservedEquation2.c);
2281	dev_info(smu->adev->dev, "ReservedEquation3{a = 0x%x b = 0x%x c = 0x%x}\n",
2282			pptable->ReservedEquation3.a,
2283			pptable->ReservedEquation3.b,
2284			pptable->ReservedEquation3.c);
2285
2286	dev_info(smu->adev->dev, "SkuReserved[0] = 0x%x\n", pptable->SkuReserved[0]);
2287	dev_info(smu->adev->dev, "SkuReserved[1] = 0x%x\n", pptable->SkuReserved[1]);
2288	dev_info(smu->adev->dev, "SkuReserved[2] = 0x%x\n", pptable->SkuReserved[2]);
2289	dev_info(smu->adev->dev, "SkuReserved[3] = 0x%x\n", pptable->SkuReserved[3]);
2290	dev_info(smu->adev->dev, "SkuReserved[4] = 0x%x\n", pptable->SkuReserved[4]);
2291	dev_info(smu->adev->dev, "SkuReserved[5] = 0x%x\n", pptable->SkuReserved[5]);
2292	dev_info(smu->adev->dev, "SkuReserved[6] = 0x%x\n", pptable->SkuReserved[6]);
2293	dev_info(smu->adev->dev, "SkuReserved[7] = 0x%x\n", pptable->SkuReserved[7]);
2294	dev_info(smu->adev->dev, "SkuReserved[8] = 0x%x\n", pptable->SkuReserved[8]);
2295	dev_info(smu->adev->dev, "SkuReserved[9] = 0x%x\n", pptable->SkuReserved[9]);
2296	dev_info(smu->adev->dev, "SkuReserved[10] = 0x%x\n", pptable->SkuReserved[10]);
2297	dev_info(smu->adev->dev, "SkuReserved[11] = 0x%x\n", pptable->SkuReserved[11]);
2298	dev_info(smu->adev->dev, "SkuReserved[12] = 0x%x\n", pptable->SkuReserved[12]);
2299	dev_info(smu->adev->dev, "SkuReserved[13] = 0x%x\n", pptable->SkuReserved[13]);
2300
2301	dev_info(smu->adev->dev, "GamingClk[0] = 0x%x\n", pptable->GamingClk[0]);
2302	dev_info(smu->adev->dev, "GamingClk[1] = 0x%x\n", pptable->GamingClk[1]);
2303	dev_info(smu->adev->dev, "GamingClk[2] = 0x%x\n", pptable->GamingClk[2]);
2304	dev_info(smu->adev->dev, "GamingClk[3] = 0x%x\n", pptable->GamingClk[3]);
2305	dev_info(smu->adev->dev, "GamingClk[4] = 0x%x\n", pptable->GamingClk[4]);
2306	dev_info(smu->adev->dev, "GamingClk[5] = 0x%x\n", pptable->GamingClk[5]);
2307
2308	for (i = 0; i < NUM_I2C_CONTROLLERS; i++) {
2309		dev_info(smu->adev->dev, "I2cControllers[%d]:\n", i);
2310		dev_info(smu->adev->dev, "                   .Enabled = 0x%x\n",
2311				pptable->I2cControllers[i].Enabled);
2312		dev_info(smu->adev->dev, "                   .Speed = 0x%x\n",
2313				pptable->I2cControllers[i].Speed);
2314		dev_info(smu->adev->dev, "                   .SlaveAddress = 0x%x\n",
2315				pptable->I2cControllers[i].SlaveAddress);
2316		dev_info(smu->adev->dev, "                   .ControllerPort = 0x%x\n",
2317				pptable->I2cControllers[i].ControllerPort);
2318		dev_info(smu->adev->dev, "                   .ControllerName = 0x%x\n",
2319				pptable->I2cControllers[i].ControllerName);
2320		dev_info(smu->adev->dev, "                   .ThermalThrottler = 0x%x\n",
2321				pptable->I2cControllers[i].ThermalThrotter);
2322		dev_info(smu->adev->dev, "                   .I2cProtocol = 0x%x\n",
2323				pptable->I2cControllers[i].I2cProtocol);
2324		dev_info(smu->adev->dev, "                   .PaddingConfig = 0x%x\n",
2325				pptable->I2cControllers[i].PaddingConfig);
2326	}
2327
2328	dev_info(smu->adev->dev, "GpioScl = 0x%x\n", pptable->GpioScl);
2329	dev_info(smu->adev->dev, "GpioSda = 0x%x\n", pptable->GpioSda);
2330	dev_info(smu->adev->dev, "FchUsbPdSlaveAddr = 0x%x\n", pptable->FchUsbPdSlaveAddr);
2331	dev_info(smu->adev->dev, "I2cSpare[0] = 0x%x\n", pptable->I2cSpare[0]);
2332
2333	dev_info(smu->adev->dev, "Board Parameters:\n");
2334	dev_info(smu->adev->dev, "VddGfxVrMapping = 0x%x\n", pptable->VddGfxVrMapping);
2335	dev_info(smu->adev->dev, "VddSocVrMapping = 0x%x\n", pptable->VddSocVrMapping);
2336	dev_info(smu->adev->dev, "VddMem0VrMapping = 0x%x\n", pptable->VddMem0VrMapping);
2337	dev_info(smu->adev->dev, "VddMem1VrMapping = 0x%x\n", pptable->VddMem1VrMapping);
2338	dev_info(smu->adev->dev, "GfxUlvPhaseSheddingMask = 0x%x\n", pptable->GfxUlvPhaseSheddingMask);
2339	dev_info(smu->adev->dev, "SocUlvPhaseSheddingMask = 0x%x\n", pptable->SocUlvPhaseSheddingMask);
2340	dev_info(smu->adev->dev, "VddciUlvPhaseSheddingMask = 0x%x\n", pptable->VddciUlvPhaseSheddingMask);
2341	dev_info(smu->adev->dev, "MvddUlvPhaseSheddingMask = 0x%x\n", pptable->MvddUlvPhaseSheddingMask);
2342
2343	dev_info(smu->adev->dev, "GfxMaxCurrent = 0x%x\n", pptable->GfxMaxCurrent);
2344	dev_info(smu->adev->dev, "GfxOffset = 0x%x\n", pptable->GfxOffset);
2345	dev_info(smu->adev->dev, "Padding_TelemetryGfx = 0x%x\n", pptable->Padding_TelemetryGfx);
2346
2347	dev_info(smu->adev->dev, "SocMaxCurrent = 0x%x\n", pptable->SocMaxCurrent);
2348	dev_info(smu->adev->dev, "SocOffset = 0x%x\n", pptable->SocOffset);
2349	dev_info(smu->adev->dev, "Padding_TelemetrySoc = 0x%x\n", pptable->Padding_TelemetrySoc);
2350
2351	dev_info(smu->adev->dev, "Mem0MaxCurrent = 0x%x\n", pptable->Mem0MaxCurrent);
2352	dev_info(smu->adev->dev, "Mem0Offset = 0x%x\n", pptable->Mem0Offset);
2353	dev_info(smu->adev->dev, "Padding_TelemetryMem0 = 0x%x\n", pptable->Padding_TelemetryMem0);
2354
2355	dev_info(smu->adev->dev, "Mem1MaxCurrent = 0x%x\n", pptable->Mem1MaxCurrent);
2356	dev_info(smu->adev->dev, "Mem1Offset = 0x%x\n", pptable->Mem1Offset);
2357	dev_info(smu->adev->dev, "Padding_TelemetryMem1 = 0x%x\n", pptable->Padding_TelemetryMem1);
2358
2359	dev_info(smu->adev->dev, "MvddRatio = 0x%x\n", pptable->MvddRatio);
2360
2361	dev_info(smu->adev->dev, "AcDcGpio = 0x%x\n", pptable->AcDcGpio);
2362	dev_info(smu->adev->dev, "AcDcPolarity = 0x%x\n", pptable->AcDcPolarity);
2363	dev_info(smu->adev->dev, "VR0HotGpio = 0x%x\n", pptable->VR0HotGpio);
2364	dev_info(smu->adev->dev, "VR0HotPolarity = 0x%x\n", pptable->VR0HotPolarity);
2365	dev_info(smu->adev->dev, "VR1HotGpio = 0x%x\n", pptable->VR1HotGpio);
2366	dev_info(smu->adev->dev, "VR1HotPolarity = 0x%x\n", pptable->VR1HotPolarity);
2367	dev_info(smu->adev->dev, "GthrGpio = 0x%x\n", pptable->GthrGpio);
2368	dev_info(smu->adev->dev, "GthrPolarity = 0x%x\n", pptable->GthrPolarity);
2369	dev_info(smu->adev->dev, "LedPin0 = 0x%x\n", pptable->LedPin0);
2370	dev_info(smu->adev->dev, "LedPin1 = 0x%x\n", pptable->LedPin1);
2371	dev_info(smu->adev->dev, "LedPin2 = 0x%x\n", pptable->LedPin2);
2372	dev_info(smu->adev->dev, "LedEnableMask = 0x%x\n", pptable->LedEnableMask);
2373	dev_info(smu->adev->dev, "LedPcie = 0x%x\n", pptable->LedPcie);
2374	dev_info(smu->adev->dev, "LedError = 0x%x\n", pptable->LedError);
2375	dev_info(smu->adev->dev, "LedSpare1[0] = 0x%x\n", pptable->LedSpare1[0]);
2376	dev_info(smu->adev->dev, "LedSpare1[1] = 0x%x\n", pptable->LedSpare1[1]);
2377
2378	dev_info(smu->adev->dev, "PllGfxclkSpreadEnabled = 0x%x\n", pptable->PllGfxclkSpreadEnabled);
2379	dev_info(smu->adev->dev, "PllGfxclkSpreadPercent = 0x%x\n", pptable->PllGfxclkSpreadPercent);
2380	dev_info(smu->adev->dev, "PllGfxclkSpreadFreq = 0x%x\n",    pptable->PllGfxclkSpreadFreq);
2381
2382	dev_info(smu->adev->dev, "DfllGfxclkSpreadEnabled = 0x%x\n", pptable->DfllGfxclkSpreadEnabled);
2383	dev_info(smu->adev->dev, "DfllGfxclkSpreadPercent = 0x%x\n", pptable->DfllGfxclkSpreadPercent);
2384	dev_info(smu->adev->dev, "DfllGfxclkSpreadFreq = 0x%x\n",    pptable->DfllGfxclkSpreadFreq);
2385
2386	dev_info(smu->adev->dev, "UclkSpreadPadding = 0x%x\n", pptable->UclkSpreadPadding);
2387	dev_info(smu->adev->dev, "UclkSpreadFreq = 0x%x\n", pptable->UclkSpreadFreq);
2388
2389	dev_info(smu->adev->dev, "FclkSpreadEnabled = 0x%x\n", pptable->FclkSpreadEnabled);
2390	dev_info(smu->adev->dev, "FclkSpreadPercent = 0x%x\n", pptable->FclkSpreadPercent);
2391	dev_info(smu->adev->dev, "FclkSpreadFreq = 0x%x\n", pptable->FclkSpreadFreq);
2392
2393	dev_info(smu->adev->dev, "MemoryChannelEnabled = 0x%x\n", pptable->MemoryChannelEnabled);
2394	dev_info(smu->adev->dev, "DramBitWidth = 0x%x\n", pptable->DramBitWidth);
2395	dev_info(smu->adev->dev, "PaddingMem1[0] = 0x%x\n", pptable->PaddingMem1[0]);
2396	dev_info(smu->adev->dev, "PaddingMem1[1] = 0x%x\n", pptable->PaddingMem1[1]);
2397	dev_info(smu->adev->dev, "PaddingMem1[2] = 0x%x\n", pptable->PaddingMem1[2]);
2398
2399	dev_info(smu->adev->dev, "TotalBoardPower = 0x%x\n", pptable->TotalBoardPower);
2400	dev_info(smu->adev->dev, "BoardPowerPadding = 0x%x\n", pptable->BoardPowerPadding);
2401
2402	dev_info(smu->adev->dev, "XgmiLinkSpeed\n");
2403	for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
2404		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiLinkSpeed[i]);
2405	dev_info(smu->adev->dev, "XgmiLinkWidth\n");
2406	for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
2407		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiLinkWidth[i]);
2408	dev_info(smu->adev->dev, "XgmiFclkFreq\n");
2409	for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
2410		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiFclkFreq[i]);
2411	dev_info(smu->adev->dev, "XgmiSocVoltage\n");
2412	for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
2413		dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiSocVoltage[i]);
2414
2415	dev_info(smu->adev->dev, "HsrEnabled = 0x%x\n", pptable->HsrEnabled);
2416	dev_info(smu->adev->dev, "VddqOffEnabled = 0x%x\n", pptable->VddqOffEnabled);
2417	dev_info(smu->adev->dev, "PaddingUmcFlags[0] = 0x%x\n", pptable->PaddingUmcFlags[0]);
2418	dev_info(smu->adev->dev, "PaddingUmcFlags[1] = 0x%x\n", pptable->PaddingUmcFlags[1]);
2419
2420	dev_info(smu->adev->dev, "BoardReserved[0] = 0x%x\n", pptable->BoardReserved[0]);
2421	dev_info(smu->adev->dev, "BoardReserved[1] = 0x%x\n", pptable->BoardReserved[1]);
2422	dev_info(smu->adev->dev, "BoardReserved[2] = 0x%x\n", pptable->BoardReserved[2]);
2423	dev_info(smu->adev->dev, "BoardReserved[3] = 0x%x\n", pptable->BoardReserved[3]);
2424	dev_info(smu->adev->dev, "BoardReserved[4] = 0x%x\n", pptable->BoardReserved[4]);
2425	dev_info(smu->adev->dev, "BoardReserved[5] = 0x%x\n", pptable->BoardReserved[5]);
2426	dev_info(smu->adev->dev, "BoardReserved[6] = 0x%x\n", pptable->BoardReserved[6]);
2427	dev_info(smu->adev->dev, "BoardReserved[7] = 0x%x\n", pptable->BoardReserved[7]);
2428	dev_info(smu->adev->dev, "BoardReserved[8] = 0x%x\n", pptable->BoardReserved[8]);
2429	dev_info(smu->adev->dev, "BoardReserved[9] = 0x%x\n", pptable->BoardReserved[9]);
2430	dev_info(smu->adev->dev, "BoardReserved[10] = 0x%x\n", pptable->BoardReserved[10]);
2431
2432	dev_info(smu->adev->dev, "MmHubPadding[0] = 0x%x\n", pptable->MmHubPadding[0]);
2433	dev_info(smu->adev->dev, "MmHubPadding[1] = 0x%x\n", pptable->MmHubPadding[1]);
2434	dev_info(smu->adev->dev, "MmHubPadding[2] = 0x%x\n", pptable->MmHubPadding[2]);
2435	dev_info(smu->adev->dev, "MmHubPadding[3] = 0x%x\n", pptable->MmHubPadding[3]);
2436	dev_info(smu->adev->dev, "MmHubPadding[4] = 0x%x\n", pptable->MmHubPadding[4]);
2437	dev_info(smu->adev->dev, "MmHubPadding[5] = 0x%x\n", pptable->MmHubPadding[5]);
2438	dev_info(smu->adev->dev, "MmHubPadding[6] = 0x%x\n", pptable->MmHubPadding[6]);
2439	dev_info(smu->adev->dev, "MmHubPadding[7] = 0x%x\n", pptable->MmHubPadding[7]);
2440}
2441
2442static void sienna_cichlid_fill_i2c_req(SwI2cRequest_t  *req, bool write,
2443				  uint8_t address, uint32_t numbytes,
2444				  uint8_t *data)
2445{
2446	int i;
2447
2448	req->I2CcontrollerPort = 0;
2449	req->I2CSpeed = 2;
2450	req->SlaveAddress = address;
2451	req->NumCmds = numbytes;
2452
2453	for (i = 0; i < numbytes; i++) {
2454		SwI2cCmd_t *cmd =  &req->SwI2cCmds[i];
2455
2456		/* First 2 bytes are always write for lower 2b EEPROM address */
2457		if (i < 2)
2458			cmd->CmdConfig = CMDCONFIG_READWRITE_MASK;
2459		else
2460			cmd->CmdConfig = write ? CMDCONFIG_READWRITE_MASK : 0;
2461
2462
2463		/* Add RESTART for read  after address filled */
2464		cmd->CmdConfig |= (i == 2 && !write) ? CMDCONFIG_RESTART_MASK : 0;
2465
2466		/* Add STOP in the end */
2467		cmd->CmdConfig |= (i == (numbytes - 1)) ? CMDCONFIG_STOP_MASK : 0;
2468
2469		/* Fill with data regardless if read or write to simplify code */
2470		cmd->ReadWriteData = data[i];
2471	}
2472}
2473
2474static int sienna_cichlid_i2c_read_data(struct i2c_adapter *control,
2475					       uint8_t address,
2476					       uint8_t *data,
2477					       uint32_t numbytes)
2478{
2479	uint32_t  i, ret = 0;
2480	SwI2cRequest_t req;
2481	struct amdgpu_device *adev = to_amdgpu_device(control);
2482	struct smu_table_context *smu_table = &adev->smu.smu_table;
2483	struct smu_table *table = &smu_table->driver_table;
2484
2485	if (numbytes > MAX_SW_I2C_COMMANDS) {
2486		dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
2487			numbytes, MAX_SW_I2C_COMMANDS);
2488		return -EINVAL;
2489	}
2490
2491	memset(&req, 0, sizeof(req));
2492	sienna_cichlid_fill_i2c_req(&req, false, address, numbytes, data);
2493
2494	mutex_lock(&adev->smu.mutex);
2495	/* Now read data starting with that address */
2496	ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req,
2497					true);
2498	mutex_unlock(&adev->smu.mutex);
2499
2500	if (!ret) {
2501		SwI2cRequest_t *res = (SwI2cRequest_t *)table->cpu_addr;
2502
2503		/* Assume SMU  fills res.SwI2cCmds[i].Data with read bytes */
2504		for (i = 0; i < numbytes; i++)
2505			data[i] = res->SwI2cCmds[i].ReadWriteData;
2506
2507		dev_dbg(adev->dev, "sienna_cichlid_i2c_read_data, address = %x, bytes = %d, data :",
2508				  (uint16_t)address, numbytes);
2509
2510		print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
2511			       8, 1, data, numbytes, false);
2512	} else
2513		dev_err(adev->dev, "sienna_cichlid_i2c_read_data - error occurred :%x", ret);
2514
2515	return ret;
2516}
2517
2518static int sienna_cichlid_i2c_write_data(struct i2c_adapter *control,
2519						uint8_t address,
2520						uint8_t *data,
2521						uint32_t numbytes)
2522{
2523	uint32_t ret;
2524	SwI2cRequest_t req;
2525	struct amdgpu_device *adev = to_amdgpu_device(control);
2526
2527	if (numbytes > MAX_SW_I2C_COMMANDS) {
2528		dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
2529			numbytes, MAX_SW_I2C_COMMANDS);
2530		return -EINVAL;
2531	}
2532
2533	memset(&req, 0, sizeof(req));
2534	sienna_cichlid_fill_i2c_req(&req, true, address, numbytes, data);
2535
2536	mutex_lock(&adev->smu.mutex);
2537	ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req, true);
2538	mutex_unlock(&adev->smu.mutex);
2539
2540	if (!ret) {
2541		dev_dbg(adev->dev, "sienna_cichlid_i2c_write(), address = %x, bytes = %d , data: ",
2542					 (uint16_t)address, numbytes);
2543
2544		print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
2545			       8, 1, data, numbytes, false);
2546		/*
2547		 * According to EEPROM spec there is a MAX of 10 ms required for
2548		 * EEPROM to flush internal RX buffer after STOP was issued at the
2549		 * end of write transaction. During this time the EEPROM will not be
2550		 * responsive to any more commands - so wait a bit more.
2551		 */
2552		msleep(10);
2553
2554	} else
2555		dev_err(adev->dev, "sienna_cichlid_i2c_write- error occurred :%x", ret);
2556
2557	return ret;
2558}
2559
2560static int sienna_cichlid_i2c_xfer(struct i2c_adapter *i2c_adap,
2561			      struct i2c_msg *msgs, int num)
2562{
2563	uint32_t  i, j, ret, data_size, data_chunk_size, next_eeprom_addr = 0;
2564	uint8_t *data_ptr, data_chunk[MAX_SW_I2C_COMMANDS] = { 0 };
2565
2566	for (i = 0; i < num; i++) {
2567		/*
2568		 * SMU interface allows at most MAX_SW_I2C_COMMANDS bytes of data at
2569		 * once and hence the data needs to be spliced into chunks and sent each
2570		 * chunk separately
2571		 */
2572		data_size = msgs[i].len - 2;
2573		data_chunk_size = MAX_SW_I2C_COMMANDS - 2;
2574		next_eeprom_addr = (msgs[i].buf[0] << 8 & 0xff00) | (msgs[i].buf[1] & 0xff);
2575		data_ptr = msgs[i].buf + 2;
2576
2577		for (j = 0; j < data_size / data_chunk_size; j++) {
2578			/* Insert the EEPROM dest addess, bits 0-15 */
2579			data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2580			data_chunk[1] = (next_eeprom_addr & 0xff);
2581
2582			if (msgs[i].flags & I2C_M_RD) {
2583				ret = sienna_cichlid_i2c_read_data(i2c_adap,
2584							     (uint8_t)msgs[i].addr,
2585							     data_chunk, MAX_SW_I2C_COMMANDS);
2586
2587				memcpy(data_ptr, data_chunk + 2, data_chunk_size);
2588			} else {
2589
2590				memcpy(data_chunk + 2, data_ptr, data_chunk_size);
2591
2592				ret = sienna_cichlid_i2c_write_data(i2c_adap,
2593							      (uint8_t)msgs[i].addr,
2594							      data_chunk, MAX_SW_I2C_COMMANDS);
2595			}
2596
2597			if (ret) {
2598				num = -EIO;
2599				goto fail;
2600			}
2601
2602			next_eeprom_addr += data_chunk_size;
2603			data_ptr += data_chunk_size;
2604		}
2605
2606		if (data_size % data_chunk_size) {
2607			data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2608			data_chunk[1] = (next_eeprom_addr & 0xff);
2609
2610			if (msgs[i].flags & I2C_M_RD) {
2611				ret = sienna_cichlid_i2c_read_data(i2c_adap,
2612							     (uint8_t)msgs[i].addr,
2613							     data_chunk, (data_size % data_chunk_size) + 2);
2614
2615				memcpy(data_ptr, data_chunk + 2, data_size % data_chunk_size);
2616			} else {
2617				memcpy(data_chunk + 2, data_ptr, data_size % data_chunk_size);
2618
2619				ret = sienna_cichlid_i2c_write_data(i2c_adap,
2620							      (uint8_t)msgs[i].addr,
2621							      data_chunk, (data_size % data_chunk_size) + 2);
2622			}
2623
2624			if (ret) {
2625				num = -EIO;
2626				goto fail;
2627			}
2628		}
2629	}
2630
2631fail:
2632	return num;
2633}
2634
2635static u32 sienna_cichlid_i2c_func(struct i2c_adapter *adap)
2636{
2637	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
2638}
2639
2640
2641static const struct i2c_algorithm sienna_cichlid_i2c_algo = {
2642	.master_xfer = sienna_cichlid_i2c_xfer,
2643	.functionality = sienna_cichlid_i2c_func,
2644};
2645
2646static int sienna_cichlid_i2c_control_init(struct smu_context *smu, struct i2c_adapter *control)
2647{
2648	struct amdgpu_device *adev = to_amdgpu_device(control);
2649	int res;
2650
2651	control->owner = THIS_MODULE;
2652	control->class = I2C_CLASS_SPD;
2653	control->dev.parent = &adev->pdev->dev;
2654	control->algo = &sienna_cichlid_i2c_algo;
2655	snprintf(control->name, sizeof(control->name), "AMDGPU SMU");
2656
2657	res = i2c_add_adapter(control);
2658	if (res)
2659		DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
2660
2661	return res;
2662}
2663
2664static void sienna_cichlid_i2c_control_fini(struct smu_context *smu, struct i2c_adapter *control)
2665{
2666	i2c_del_adapter(control);
2667}
2668
2669
2670static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
2671	.get_allowed_feature_mask = sienna_cichlid_get_allowed_feature_mask,
2672	.set_default_dpm_table = sienna_cichlid_set_default_dpm_table,
2673	.dpm_set_vcn_enable = sienna_cichlid_dpm_set_vcn_enable,
2674	.dpm_set_jpeg_enable = sienna_cichlid_dpm_set_jpeg_enable,
2675	.i2c_init = sienna_cichlid_i2c_control_init,
2676	.i2c_fini = sienna_cichlid_i2c_control_fini,
2677	.print_clk_levels = sienna_cichlid_print_clk_levels,
2678	.force_clk_levels = sienna_cichlid_force_clk_levels,
2679	.populate_umd_state_clk = sienna_cichlid_populate_umd_state_clk,
2680	.pre_display_config_changed = sienna_cichlid_pre_display_config_changed,
2681	.display_config_changed = sienna_cichlid_display_config_changed,
2682	.notify_smc_display_config = sienna_cichlid_notify_smc_display_config,
2683	.is_dpm_running = sienna_cichlid_is_dpm_running,
2684	.get_fan_speed_percent = sienna_cichlid_get_fan_speed_percent,
2685	.get_fan_speed_rpm = sienna_cichlid_get_fan_speed_rpm,
2686	.get_power_profile_mode = sienna_cichlid_get_power_profile_mode,
2687	.set_power_profile_mode = sienna_cichlid_set_power_profile_mode,
2688	.set_watermarks_table = sienna_cichlid_set_watermarks_table,
2689	.read_sensor = sienna_cichlid_read_sensor,
2690	.get_uclk_dpm_states = sienna_cichlid_get_uclk_dpm_states,
2691	.set_performance_level = smu_v11_0_set_performance_level,
2692	.get_thermal_temperature_range = sienna_cichlid_get_thermal_temperature_range,
2693	.display_disable_memory_clock_switch = sienna_cichlid_display_disable_memory_clock_switch,
2694	.get_power_limit = sienna_cichlid_get_power_limit,
2695	.update_pcie_parameters = sienna_cichlid_update_pcie_parameters,
2696	.dump_pptable = sienna_cichlid_dump_pptable,
2697	.init_microcode = smu_v11_0_init_microcode,
2698	.load_microcode = smu_v11_0_load_microcode,
2699	.init_smc_tables = sienna_cichlid_init_smc_tables,
2700	.fini_smc_tables = smu_v11_0_fini_smc_tables,
2701	.init_power = smu_v11_0_init_power,
2702	.fini_power = smu_v11_0_fini_power,
2703	.check_fw_status = smu_v11_0_check_fw_status,
2704	.setup_pptable = sienna_cichlid_setup_pptable,
2705	.get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
2706	.check_fw_version = smu_v11_0_check_fw_version,
2707	.write_pptable = smu_cmn_write_pptable,
2708	.set_driver_table_location = smu_v11_0_set_driver_table_location,
2709	.set_tool_table_location = smu_v11_0_set_tool_table_location,
2710	.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
2711	.system_features_control = smu_v11_0_system_features_control,
2712	.send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
2713	.send_smc_msg = smu_cmn_send_smc_msg,
2714	.init_display_count = NULL,
2715	.set_allowed_mask = smu_v11_0_set_allowed_mask,
2716	.get_enabled_mask = smu_cmn_get_enabled_mask,
2717	.feature_is_enabled = smu_cmn_feature_is_enabled,
2718	.disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception,
2719	.notify_display_change = NULL,
2720	.set_power_limit = smu_v11_0_set_power_limit,
2721	.init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
2722	.enable_thermal_alert = smu_v11_0_enable_thermal_alert,
2723	.disable_thermal_alert = smu_v11_0_disable_thermal_alert,
2724	.set_min_dcef_deep_sleep = NULL,
2725	.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
2726	.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
2727	.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
2728	.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
2729	.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
2730	.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
2731	.gfx_off_control = smu_v11_0_gfx_off_control,
2732	.register_irq_handler = smu_v11_0_register_irq_handler,
2733	.set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
2734	.get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
2735	.baco_is_support= sienna_cichlid_is_baco_supported,
2736	.baco_get_state = smu_v11_0_baco_get_state,
2737	.baco_set_state = smu_v11_0_baco_set_state,
2738	.baco_enter = smu_v11_0_baco_enter,
2739	.baco_exit = smu_v11_0_baco_exit,
2740	.mode1_reset_is_support = sienna_cichlid_is_mode1_reset_supported,
2741	.mode1_reset = smu_v11_0_mode1_reset,
2742	.get_dpm_ultimate_freq = sienna_cichlid_get_dpm_ultimate_freq,
2743	.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
2744	.run_btc = sienna_cichlid_run_btc,
2745	.get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
2746	.set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
2747};
2748
2749void sienna_cichlid_set_ppt_funcs(struct smu_context *smu)
2750{
2751	smu->ppt_funcs = &sienna_cichlid_ppt_funcs;
2752	smu->message_map = sienna_cichlid_message_map;
2753	smu->clock_map = sienna_cichlid_clk_map;
2754	smu->feature_map = sienna_cichlid_feature_mask_map;
2755	smu->table_map = sienna_cichlid_table_map;
2756	smu->pwr_src_map = sienna_cichlid_pwr_src_map;
2757	smu->workload_map = sienna_cichlid_workload_map;
2758}