cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

arcturus_ppt.c (86866B)


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