Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2019 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #define SWSMU_CODE_LAYER_L2
0025 
0026 #include <linux/firmware.h>
0027 #include "amdgpu.h"
0028 #include "amdgpu_dpm.h"
0029 #include "amdgpu_smu.h"
0030 #include "atomfirmware.h"
0031 #include "amdgpu_atomfirmware.h"
0032 #include "amdgpu_atombios.h"
0033 #include "smu_v13_0.h"
0034 #include "smu13_driver_if_aldebaran.h"
0035 #include "soc15_common.h"
0036 #include "atom.h"
0037 #include "aldebaran_ppt.h"
0038 #include "smu_v13_0_pptable.h"
0039 #include "aldebaran_ppsmc.h"
0040 #include "nbio/nbio_7_4_offset.h"
0041 #include "nbio/nbio_7_4_sh_mask.h"
0042 #include "thm/thm_11_0_2_offset.h"
0043 #include "thm/thm_11_0_2_sh_mask.h"
0044 #include "amdgpu_xgmi.h"
0045 #include <linux/pci.h>
0046 #include "amdgpu_ras.h"
0047 #include "smu_cmn.h"
0048 #include "mp/mp_13_0_2_offset.h"
0049 
0050 /*
0051  * DO NOT use these for err/warn/info/debug messages.
0052  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
0053  * They are more MGPU friendly.
0054  */
0055 #undef pr_err
0056 #undef pr_warn
0057 #undef pr_info
0058 #undef pr_debug
0059 
0060 #define ALDEBARAN_FEA_MAP(smu_feature, aldebaran_feature) \
0061     [smu_feature] = {1, (aldebaran_feature)}
0062 
0063 #define FEATURE_MASK(feature) (1ULL << feature)
0064 #define SMC_DPM_FEATURE ( \
0065               FEATURE_MASK(FEATURE_DATA_CALCULATIONS) | \
0066               FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT)  | \
0067               FEATURE_MASK(FEATURE_DPM_UCLK_BIT)    | \
0068               FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT)  | \
0069               FEATURE_MASK(FEATURE_DPM_FCLK_BIT)    | \
0070               FEATURE_MASK(FEATURE_DPM_LCLK_BIT)    | \
0071               FEATURE_MASK(FEATURE_DPM_XGMI_BIT)    | \
0072               FEATURE_MASK(FEATURE_DPM_VCN_BIT))
0073 
0074 /* possible frequency drift (1Mhz) */
0075 #define EPSILON             1
0076 
0077 #define smnPCIE_ESM_CTRL            0x111003D0
0078 
0079 /*
0080  * SMU support ECCTABLE since version 68.42.0,
0081  * use this to check ECCTALE feature whether support
0082  */
0083 #define SUPPORT_ECCTABLE_SMU_VERSION 0x00442a00
0084 
0085 /*
0086  * SMU support mca_ceumc_addr in ECCTABLE since version 68.55.0,
0087  * use this to check mca_ceumc_addr record whether support
0088  */
0089 #define SUPPORT_ECCTABLE_V2_SMU_VERSION 0x00443700
0090 
0091 /*
0092  * SMU support BAD CHENNEL info MSG since version 68.51.00,
0093  * use this to check ECCTALE feature whether support
0094  */
0095 #define SUPPORT_BAD_CHANNEL_INFO_MSG_VERSION 0x00443300
0096 
0097 static const struct smu_temperature_range smu13_thermal_policy[] =
0098 {
0099     {-273150,  99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000},
0100     { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000},
0101 };
0102 
0103 static const struct cmn2asic_msg_mapping aldebaran_message_map[SMU_MSG_MAX_COUNT] = {
0104     MSG_MAP(TestMessage,                 PPSMC_MSG_TestMessage,         0),
0105     MSG_MAP(GetSmuVersion,               PPSMC_MSG_GetSmuVersion,           1),
0106     MSG_MAP(GetDriverIfVersion,          PPSMC_MSG_GetDriverIfVersion,      1),
0107     MSG_MAP(EnableAllSmuFeatures,            PPSMC_MSG_EnableAllSmuFeatures,        0),
0108     MSG_MAP(DisableAllSmuFeatures,           PPSMC_MSG_DisableAllSmuFeatures,       0),
0109     MSG_MAP(GetEnabledSmuFeaturesLow,        PPSMC_MSG_GetEnabledSmuFeaturesLow,    1),
0110     MSG_MAP(GetEnabledSmuFeaturesHigh,       PPSMC_MSG_GetEnabledSmuFeaturesHigh,   1),
0111     MSG_MAP(SetDriverDramAddrHigh,           PPSMC_MSG_SetDriverDramAddrHigh,       1),
0112     MSG_MAP(SetDriverDramAddrLow,            PPSMC_MSG_SetDriverDramAddrLow,        1),
0113     MSG_MAP(SetToolsDramAddrHigh,            PPSMC_MSG_SetToolsDramAddrHigh,        0),
0114     MSG_MAP(SetToolsDramAddrLow,             PPSMC_MSG_SetToolsDramAddrLow,     0),
0115     MSG_MAP(TransferTableSmu2Dram,           PPSMC_MSG_TransferTableSmu2Dram,       1),
0116     MSG_MAP(TransferTableDram2Smu,           PPSMC_MSG_TransferTableDram2Smu,       0),
0117     MSG_MAP(UseDefaultPPTable,           PPSMC_MSG_UseDefaultPPTable,       0),
0118     MSG_MAP(SetSystemVirtualDramAddrHigh,        PPSMC_MSG_SetSystemVirtualDramAddrHigh,    0),
0119     MSG_MAP(SetSystemVirtualDramAddrLow,         PPSMC_MSG_SetSystemVirtualDramAddrLow, 0),
0120     MSG_MAP(SetSoftMinByFreq,            PPSMC_MSG_SetSoftMinByFreq,        0),
0121     MSG_MAP(SetSoftMaxByFreq,            PPSMC_MSG_SetSoftMaxByFreq,        0),
0122     MSG_MAP(SetHardMinByFreq,            PPSMC_MSG_SetHardMinByFreq,        0),
0123     MSG_MAP(SetHardMaxByFreq,            PPSMC_MSG_SetHardMaxByFreq,        0),
0124     MSG_MAP(GetMinDpmFreq,               PPSMC_MSG_GetMinDpmFreq,           0),
0125     MSG_MAP(GetMaxDpmFreq,               PPSMC_MSG_GetMaxDpmFreq,           0),
0126     MSG_MAP(GetDpmFreqByIndex,           PPSMC_MSG_GetDpmFreqByIndex,       1),
0127     MSG_MAP(SetWorkloadMask,             PPSMC_MSG_SetWorkloadMask,         1),
0128     MSG_MAP(GetVoltageByDpm,             PPSMC_MSG_GetVoltageByDpm,         0),
0129     MSG_MAP(GetVoltageByDpmOverdrive,        PPSMC_MSG_GetVoltageByDpmOverdrive,    0),
0130     MSG_MAP(SetPptLimit,                 PPSMC_MSG_SetPptLimit,         0),
0131     MSG_MAP(GetPptLimit,                 PPSMC_MSG_GetPptLimit,         1),
0132     MSG_MAP(PrepareMp1ForUnload,             PPSMC_MSG_PrepareMp1ForUnload,     0),
0133     MSG_MAP(GfxDeviceDriverReset,            PPSMC_MSG_GfxDriverReset,          0),
0134     MSG_MAP(RunDcBtc,                PPSMC_MSG_RunDcBtc,            0),
0135     MSG_MAP(DramLogSetDramAddrHigh,          PPSMC_MSG_DramLogSetDramAddrHigh,      0),
0136     MSG_MAP(DramLogSetDramAddrLow,           PPSMC_MSG_DramLogSetDramAddrLow,       0),
0137     MSG_MAP(DramLogSetDramSize,          PPSMC_MSG_DramLogSetDramSize,      0),
0138     MSG_MAP(GetDebugData,                PPSMC_MSG_GetDebugData,            0),
0139     MSG_MAP(WaflTest,                PPSMC_MSG_WaflTest,            0),
0140     MSG_MAP(SetMemoryChannelEnable,          PPSMC_MSG_SetMemoryChannelEnable,      0),
0141     MSG_MAP(SetNumBadHbmPagesRetired,        PPSMC_MSG_SetNumBadHbmPagesRetired,    0),
0142     MSG_MAP(DFCstateControl,             PPSMC_MSG_DFCstateControl,         0),
0143     MSG_MAP(GetGmiPwrDnHyst,             PPSMC_MSG_GetGmiPwrDnHyst,         0),
0144     MSG_MAP(SetGmiPwrDnHyst,             PPSMC_MSG_SetGmiPwrDnHyst,         0),
0145     MSG_MAP(GmiPwrDnControl,             PPSMC_MSG_GmiPwrDnControl,         0),
0146     MSG_MAP(EnterGfxoff,                 PPSMC_MSG_EnterGfxoff,         0),
0147     MSG_MAP(ExitGfxoff,              PPSMC_MSG_ExitGfxoff,          0),
0148     MSG_MAP(SetExecuteDMATest,           PPSMC_MSG_SetExecuteDMATest,       0),
0149     MSG_MAP(EnableDeterminism,           PPSMC_MSG_EnableDeterminism,       0),
0150     MSG_MAP(DisableDeterminism,          PPSMC_MSG_DisableDeterminism,      0),
0151     MSG_MAP(SetUclkDpmMode,              PPSMC_MSG_SetUclkDpmMode,          0),
0152     MSG_MAP(GfxDriverResetRecovery,          PPSMC_MSG_GfxDriverResetRecovery,      0),
0153     MSG_MAP(BoardPowerCalibration,           PPSMC_MSG_BoardPowerCalibration,       0),
0154     MSG_MAP(HeavySBR,                            PPSMC_MSG_HeavySBR,                        0),
0155     MSG_MAP(SetBadHBMPagesRetiredFlagsPerChannel,   PPSMC_MSG_SetBadHBMPagesRetiredFlagsPerChannel, 0),
0156 };
0157 
0158 static const struct cmn2asic_mapping aldebaran_clk_map[SMU_CLK_COUNT] = {
0159     CLK_MAP(GFXCLK, PPCLK_GFXCLK),
0160     CLK_MAP(SCLK,   PPCLK_GFXCLK),
0161     CLK_MAP(SOCCLK, PPCLK_SOCCLK),
0162     CLK_MAP(FCLK, PPCLK_FCLK),
0163     CLK_MAP(UCLK, PPCLK_UCLK),
0164     CLK_MAP(MCLK, PPCLK_UCLK),
0165     CLK_MAP(DCLK, PPCLK_DCLK),
0166     CLK_MAP(VCLK, PPCLK_VCLK),
0167     CLK_MAP(LCLK,   PPCLK_LCLK),
0168 };
0169 
0170 static const struct cmn2asic_mapping aldebaran_feature_mask_map[SMU_FEATURE_COUNT] = {
0171     ALDEBARAN_FEA_MAP(SMU_FEATURE_DATA_CALCULATIONS_BIT,        FEATURE_DATA_CALCULATIONS),
0172     ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_GFXCLK_BIT,           FEATURE_DPM_GFXCLK_BIT),
0173     ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_UCLK_BIT,             FEATURE_DPM_UCLK_BIT),
0174     ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_SOCCLK_BIT,           FEATURE_DPM_SOCCLK_BIT),
0175     ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_FCLK_BIT,             FEATURE_DPM_FCLK_BIT),
0176     ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_LCLK_BIT,             FEATURE_DPM_LCLK_BIT),
0177     ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_XGMI_BIT,                 FEATURE_DPM_XGMI_BIT),
0178     ALDEBARAN_FEA_MAP(SMU_FEATURE_DS_GFXCLK_BIT,            FEATURE_DS_GFXCLK_BIT),
0179     ALDEBARAN_FEA_MAP(SMU_FEATURE_DS_SOCCLK_BIT,            FEATURE_DS_SOCCLK_BIT),
0180     ALDEBARAN_FEA_MAP(SMU_FEATURE_DS_LCLK_BIT,              FEATURE_DS_LCLK_BIT),
0181     ALDEBARAN_FEA_MAP(SMU_FEATURE_DS_FCLK_BIT,              FEATURE_DS_FCLK_BIT),
0182     ALDEBARAN_FEA_MAP(SMU_FEATURE_DS_UCLK_BIT,              FEATURE_DS_UCLK_BIT),
0183     ALDEBARAN_FEA_MAP(SMU_FEATURE_GFX_SS_BIT,               FEATURE_GFX_SS_BIT),
0184     ALDEBARAN_FEA_MAP(SMU_FEATURE_VCN_DPM_BIT,              FEATURE_DPM_VCN_BIT),
0185     ALDEBARAN_FEA_MAP(SMU_FEATURE_RSMU_SMN_CG_BIT,          FEATURE_RSMU_SMN_CG_BIT),
0186     ALDEBARAN_FEA_MAP(SMU_FEATURE_WAFL_CG_BIT,              FEATURE_WAFL_CG_BIT),
0187     ALDEBARAN_FEA_MAP(SMU_FEATURE_PPT_BIT,                  FEATURE_PPT_BIT),
0188     ALDEBARAN_FEA_MAP(SMU_FEATURE_TDC_BIT,                  FEATURE_TDC_BIT),
0189     ALDEBARAN_FEA_MAP(SMU_FEATURE_APCC_PLUS_BIT,            FEATURE_APCC_PLUS_BIT),
0190     ALDEBARAN_FEA_MAP(SMU_FEATURE_APCC_DFLL_BIT,            FEATURE_APCC_DFLL_BIT),
0191     ALDEBARAN_FEA_MAP(SMU_FEATURE_FUSE_CG_BIT,              FEATURE_FUSE_CG_BIT),
0192     ALDEBARAN_FEA_MAP(SMU_FEATURE_MP1_CG_BIT,               FEATURE_MP1_CG_BIT),
0193     ALDEBARAN_FEA_MAP(SMU_FEATURE_SMUIO_CG_BIT,             FEATURE_SMUIO_CG_BIT),
0194     ALDEBARAN_FEA_MAP(SMU_FEATURE_THM_CG_BIT,               FEATURE_THM_CG_BIT),
0195     ALDEBARAN_FEA_MAP(SMU_FEATURE_CLK_CG_BIT,               FEATURE_CLK_CG_BIT),
0196     ALDEBARAN_FEA_MAP(SMU_FEATURE_FW_CTF_BIT,               FEATURE_FW_CTF_BIT),
0197     ALDEBARAN_FEA_MAP(SMU_FEATURE_THERMAL_BIT,              FEATURE_THERMAL_BIT),
0198     ALDEBARAN_FEA_MAP(SMU_FEATURE_OUT_OF_BAND_MONITOR_BIT,  FEATURE_OUT_OF_BAND_MONITOR_BIT),
0199     ALDEBARAN_FEA_MAP(SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT,FEATURE_XGMI_PER_LINK_PWR_DWN),
0200     ALDEBARAN_FEA_MAP(SMU_FEATURE_DF_CSTATE_BIT,            FEATURE_DF_CSTATE),
0201 };
0202 
0203 static const struct cmn2asic_mapping aldebaran_table_map[SMU_TABLE_COUNT] = {
0204     TAB_MAP(PPTABLE),
0205     TAB_MAP(AVFS_PSM_DEBUG),
0206     TAB_MAP(AVFS_FUSE_OVERRIDE),
0207     TAB_MAP(PMSTATUSLOG),
0208     TAB_MAP(SMU_METRICS),
0209     TAB_MAP(DRIVER_SMU_CONFIG),
0210     TAB_MAP(I2C_COMMANDS),
0211     TAB_MAP(ECCINFO),
0212 };
0213 
0214 static const uint8_t aldebaran_throttler_map[] = {
0215     [THROTTLER_PPT0_BIT]        = (SMU_THROTTLER_PPT0_BIT),
0216     [THROTTLER_PPT1_BIT]        = (SMU_THROTTLER_PPT1_BIT),
0217     [THROTTLER_TDC_GFX_BIT]     = (SMU_THROTTLER_TDC_GFX_BIT),
0218     [THROTTLER_TDC_SOC_BIT]     = (SMU_THROTTLER_TDC_SOC_BIT),
0219     [THROTTLER_TDC_HBM_BIT]     = (SMU_THROTTLER_TDC_MEM_BIT),
0220     [THROTTLER_TEMP_GPU_BIT]    = (SMU_THROTTLER_TEMP_GPU_BIT),
0221     [THROTTLER_TEMP_MEM_BIT]    = (SMU_THROTTLER_TEMP_MEM_BIT),
0222     [THROTTLER_TEMP_VR_GFX_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
0223     [THROTTLER_TEMP_VR_SOC_BIT] = (SMU_THROTTLER_TEMP_VR_SOC_BIT),
0224     [THROTTLER_TEMP_VR_MEM_BIT] = (SMU_THROTTLER_TEMP_VR_MEM0_BIT),
0225     [THROTTLER_APCC_BIT]        = (SMU_THROTTLER_APCC_BIT),
0226 };
0227 
0228 static int aldebaran_tables_init(struct smu_context *smu)
0229 {
0230     struct smu_table_context *smu_table = &smu->smu_table;
0231     struct smu_table *tables = smu_table->tables;
0232 
0233     SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
0234                PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
0235 
0236     SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU13_TOOL_SIZE,
0237                PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
0238 
0239     SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
0240                PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
0241 
0242     SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
0243                PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
0244 
0245     SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t),
0246                PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
0247 
0248     smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
0249     if (!smu_table->metrics_table)
0250         return -ENOMEM;
0251     smu_table->metrics_time = 0;
0252 
0253     smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_3);
0254     smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
0255     if (!smu_table->gpu_metrics_table) {
0256         kfree(smu_table->metrics_table);
0257         return -ENOMEM;
0258     }
0259 
0260     smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL);
0261     if (!smu_table->ecc_table)
0262         return -ENOMEM;
0263 
0264     return 0;
0265 }
0266 
0267 static int aldebaran_allocate_dpm_context(struct smu_context *smu)
0268 {
0269     struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
0270 
0271     smu_dpm->dpm_context = kzalloc(sizeof(struct smu_13_0_dpm_context),
0272                        GFP_KERNEL);
0273     if (!smu_dpm->dpm_context)
0274         return -ENOMEM;
0275     smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context);
0276 
0277     return 0;
0278 }
0279 
0280 static int aldebaran_init_smc_tables(struct smu_context *smu)
0281 {
0282     int ret = 0;
0283 
0284     ret = aldebaran_tables_init(smu);
0285     if (ret)
0286         return ret;
0287 
0288     ret = aldebaran_allocate_dpm_context(smu);
0289     if (ret)
0290         return ret;
0291 
0292     return smu_v13_0_init_smc_tables(smu);
0293 }
0294 
0295 static int aldebaran_get_allowed_feature_mask(struct smu_context *smu,
0296                           uint32_t *feature_mask, uint32_t num)
0297 {
0298     if (num > 2)
0299         return -EINVAL;
0300 
0301     /* pptable will handle the features to enable */
0302     memset(feature_mask, 0xFF, sizeof(uint32_t) * num);
0303 
0304     return 0;
0305 }
0306 
0307 static int aldebaran_set_default_dpm_table(struct smu_context *smu)
0308 {
0309     struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
0310     struct smu_13_0_dpm_table *dpm_table = NULL;
0311     PPTable_t *pptable = smu->smu_table.driver_pptable;
0312     int ret = 0;
0313 
0314     /* socclk dpm table setup */
0315     dpm_table = &dpm_context->dpm_tables.soc_table;
0316     if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
0317         ret = smu_v13_0_set_single_dpm_table(smu,
0318                              SMU_SOCCLK,
0319                              dpm_table);
0320         if (ret)
0321             return ret;
0322     } else {
0323         dpm_table->count = 1;
0324         dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
0325         dpm_table->dpm_levels[0].enabled = true;
0326         dpm_table->min = dpm_table->dpm_levels[0].value;
0327         dpm_table->max = dpm_table->dpm_levels[0].value;
0328     }
0329 
0330     /* gfxclk dpm table setup */
0331     dpm_table = &dpm_context->dpm_tables.gfx_table;
0332     if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
0333         /* in the case of gfxclk, only fine-grained dpm is honored */
0334         dpm_table->count = 2;
0335         dpm_table->dpm_levels[0].value = pptable->GfxclkFmin;
0336         dpm_table->dpm_levels[0].enabled = true;
0337         dpm_table->dpm_levels[1].value = pptable->GfxclkFmax;
0338         dpm_table->dpm_levels[1].enabled = true;
0339         dpm_table->min = dpm_table->dpm_levels[0].value;
0340         dpm_table->max = dpm_table->dpm_levels[1].value;
0341     } else {
0342         dpm_table->count = 1;
0343         dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
0344         dpm_table->dpm_levels[0].enabled = true;
0345         dpm_table->min = dpm_table->dpm_levels[0].value;
0346         dpm_table->max = dpm_table->dpm_levels[0].value;
0347     }
0348 
0349     /* memclk dpm table setup */
0350     dpm_table = &dpm_context->dpm_tables.uclk_table;
0351     if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
0352         ret = smu_v13_0_set_single_dpm_table(smu,
0353                              SMU_UCLK,
0354                              dpm_table);
0355         if (ret)
0356             return ret;
0357     } else {
0358         dpm_table->count = 1;
0359         dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
0360         dpm_table->dpm_levels[0].enabled = true;
0361         dpm_table->min = dpm_table->dpm_levels[0].value;
0362         dpm_table->max = dpm_table->dpm_levels[0].value;
0363     }
0364 
0365     /* fclk dpm table setup */
0366     dpm_table = &dpm_context->dpm_tables.fclk_table;
0367     if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
0368         ret = smu_v13_0_set_single_dpm_table(smu,
0369                              SMU_FCLK,
0370                              dpm_table);
0371         if (ret)
0372             return ret;
0373     } else {
0374         dpm_table->count = 1;
0375         dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.fclk / 100;
0376         dpm_table->dpm_levels[0].enabled = true;
0377         dpm_table->min = dpm_table->dpm_levels[0].value;
0378         dpm_table->max = dpm_table->dpm_levels[0].value;
0379     }
0380 
0381     return 0;
0382 }
0383 
0384 static int aldebaran_check_powerplay_table(struct smu_context *smu)
0385 {
0386     struct smu_table_context *table_context = &smu->smu_table;
0387     struct smu_13_0_powerplay_table *powerplay_table =
0388         table_context->power_play_table;
0389 
0390     table_context->thermal_controller_type =
0391         powerplay_table->thermal_controller_type;
0392 
0393     return 0;
0394 }
0395 
0396 static int aldebaran_store_powerplay_table(struct smu_context *smu)
0397 {
0398     struct smu_table_context *table_context = &smu->smu_table;
0399     struct smu_13_0_powerplay_table *powerplay_table =
0400         table_context->power_play_table;
0401     memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
0402            sizeof(PPTable_t));
0403 
0404     return 0;
0405 }
0406 
0407 static int aldebaran_append_powerplay_table(struct smu_context *smu)
0408 {
0409     struct smu_table_context *table_context = &smu->smu_table;
0410     PPTable_t *smc_pptable = table_context->driver_pptable;
0411     struct atom_smc_dpm_info_v4_10 *smc_dpm_table;
0412     int index, ret;
0413 
0414     index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
0415                        smc_dpm_info);
0416 
0417     ret = amdgpu_atombios_get_data_table(smu->adev, index, NULL, NULL, NULL,
0418                       (uint8_t **)&smc_dpm_table);
0419     if (ret)
0420         return ret;
0421 
0422     dev_info(smu->adev->dev, "smc_dpm_info table revision(format.content): %d.%d\n",
0423             smc_dpm_table->table_header.format_revision,
0424             smc_dpm_table->table_header.content_revision);
0425 
0426     if ((smc_dpm_table->table_header.format_revision == 4) &&
0427         (smc_dpm_table->table_header.content_revision == 10))
0428         smu_memcpy_trailing(smc_pptable, GfxMaxCurrent, reserved,
0429                     smc_dpm_table, GfxMaxCurrent);
0430     return 0;
0431 }
0432 
0433 static int aldebaran_setup_pptable(struct smu_context *smu)
0434 {
0435     int ret = 0;
0436 
0437     /* VBIOS pptable is the first choice */
0438     smu->smu_table.boot_values.pp_table_id = 0;
0439 
0440     ret = smu_v13_0_setup_pptable(smu);
0441     if (ret)
0442         return ret;
0443 
0444     ret = aldebaran_store_powerplay_table(smu);
0445     if (ret)
0446         return ret;
0447 
0448     ret = aldebaran_append_powerplay_table(smu);
0449     if (ret)
0450         return ret;
0451 
0452     ret = aldebaran_check_powerplay_table(smu);
0453     if (ret)
0454         return ret;
0455 
0456     return ret;
0457 }
0458 
0459 static bool aldebaran_is_primary(struct smu_context *smu)
0460 {
0461     struct amdgpu_device *adev = smu->adev;
0462 
0463     if (adev->smuio.funcs && adev->smuio.funcs->get_die_id)
0464         return adev->smuio.funcs->get_die_id(adev) == 0;
0465 
0466     return true;
0467 }
0468 
0469 static int aldebaran_run_board_btc(struct smu_context *smu)
0470 {
0471     u32 smu_version;
0472     int ret;
0473 
0474     if (!aldebaran_is_primary(smu))
0475         return 0;
0476 
0477     ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
0478     if (ret) {
0479         dev_err(smu->adev->dev, "Failed to get smu version!\n");
0480         return ret;
0481     }
0482     if (smu_version <= 0x00441d00)
0483         return 0;
0484 
0485     ret = smu_cmn_send_smc_msg(smu, SMU_MSG_BoardPowerCalibration, NULL);
0486     if (ret)
0487         dev_err(smu->adev->dev, "Board power calibration failed!\n");
0488 
0489     return ret;
0490 }
0491 
0492 static int aldebaran_run_btc(struct smu_context *smu)
0493 {
0494     int ret;
0495 
0496     ret = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
0497     if (ret)
0498         dev_err(smu->adev->dev, "RunDcBtc failed!\n");
0499     else
0500         ret = aldebaran_run_board_btc(smu);
0501 
0502     return ret;
0503 }
0504 
0505 static int aldebaran_populate_umd_state_clk(struct smu_context *smu)
0506 {
0507     struct smu_13_0_dpm_context *dpm_context =
0508         smu->smu_dpm.dpm_context;
0509     struct smu_13_0_dpm_table *gfx_table =
0510         &dpm_context->dpm_tables.gfx_table;
0511     struct smu_13_0_dpm_table *mem_table =
0512         &dpm_context->dpm_tables.uclk_table;
0513     struct smu_13_0_dpm_table *soc_table =
0514         &dpm_context->dpm_tables.soc_table;
0515     struct smu_umd_pstate_table *pstate_table =
0516         &smu->pstate_table;
0517 
0518     pstate_table->gfxclk_pstate.min = gfx_table->min;
0519     pstate_table->gfxclk_pstate.peak = gfx_table->max;
0520     pstate_table->gfxclk_pstate.curr.min = gfx_table->min;
0521     pstate_table->gfxclk_pstate.curr.max = gfx_table->max;
0522 
0523     pstate_table->uclk_pstate.min = mem_table->min;
0524     pstate_table->uclk_pstate.peak = mem_table->max;
0525     pstate_table->uclk_pstate.curr.min = mem_table->min;
0526     pstate_table->uclk_pstate.curr.max = mem_table->max;
0527 
0528     pstate_table->socclk_pstate.min = soc_table->min;
0529     pstate_table->socclk_pstate.peak = soc_table->max;
0530     pstate_table->socclk_pstate.curr.min = soc_table->min;
0531     pstate_table->socclk_pstate.curr.max = soc_table->max;
0532 
0533     if (gfx_table->count > ALDEBARAN_UMD_PSTATE_GFXCLK_LEVEL &&
0534         mem_table->count > ALDEBARAN_UMD_PSTATE_MCLK_LEVEL &&
0535         soc_table->count > ALDEBARAN_UMD_PSTATE_SOCCLK_LEVEL) {
0536         pstate_table->gfxclk_pstate.standard =
0537             gfx_table->dpm_levels[ALDEBARAN_UMD_PSTATE_GFXCLK_LEVEL].value;
0538         pstate_table->uclk_pstate.standard =
0539             mem_table->dpm_levels[ALDEBARAN_UMD_PSTATE_MCLK_LEVEL].value;
0540         pstate_table->socclk_pstate.standard =
0541             soc_table->dpm_levels[ALDEBARAN_UMD_PSTATE_SOCCLK_LEVEL].value;
0542     } else {
0543         pstate_table->gfxclk_pstate.standard =
0544             pstate_table->gfxclk_pstate.min;
0545         pstate_table->uclk_pstate.standard =
0546             pstate_table->uclk_pstate.min;
0547         pstate_table->socclk_pstate.standard =
0548             pstate_table->socclk_pstate.min;
0549     }
0550 
0551     return 0;
0552 }
0553 
0554 static int aldebaran_get_clk_table(struct smu_context *smu,
0555                    struct pp_clock_levels_with_latency *clocks,
0556                    struct smu_13_0_dpm_table *dpm_table)
0557 {
0558     uint32_t i;
0559 
0560     clocks->num_levels = min_t(uint32_t,
0561                    dpm_table->count,
0562                    (uint32_t)PP_MAX_CLOCK_LEVELS);
0563 
0564     for (i = 0; i < clocks->num_levels; i++) {
0565         clocks->data[i].clocks_in_khz =
0566             dpm_table->dpm_levels[i].value * 1000;
0567         clocks->data[i].latency_in_us = 0;
0568     }
0569 
0570     return 0;
0571 }
0572 
0573 static int aldebaran_freqs_in_same_level(int32_t frequency1,
0574                      int32_t frequency2)
0575 {
0576     return (abs(frequency1 - frequency2) <= EPSILON);
0577 }
0578 
0579 static int aldebaran_get_smu_metrics_data(struct smu_context *smu,
0580                       MetricsMember_t member,
0581                       uint32_t *value)
0582 {
0583     struct smu_table_context *smu_table= &smu->smu_table;
0584     SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
0585     int ret = 0;
0586 
0587     ret = smu_cmn_get_metrics_table(smu,
0588                     NULL,
0589                     false);
0590     if (ret)
0591         return ret;
0592 
0593     switch (member) {
0594     case METRICS_CURR_GFXCLK:
0595         *value = metrics->CurrClock[PPCLK_GFXCLK];
0596         break;
0597     case METRICS_CURR_SOCCLK:
0598         *value = metrics->CurrClock[PPCLK_SOCCLK];
0599         break;
0600     case METRICS_CURR_UCLK:
0601         *value = metrics->CurrClock[PPCLK_UCLK];
0602         break;
0603     case METRICS_CURR_VCLK:
0604         *value = metrics->CurrClock[PPCLK_VCLK];
0605         break;
0606     case METRICS_CURR_DCLK:
0607         *value = metrics->CurrClock[PPCLK_DCLK];
0608         break;
0609     case METRICS_CURR_FCLK:
0610         *value = metrics->CurrClock[PPCLK_FCLK];
0611         break;
0612     case METRICS_AVERAGE_GFXCLK:
0613         *value = metrics->AverageGfxclkFrequency;
0614         break;
0615     case METRICS_AVERAGE_SOCCLK:
0616         *value = metrics->AverageSocclkFrequency;
0617         break;
0618     case METRICS_AVERAGE_UCLK:
0619         *value = metrics->AverageUclkFrequency;
0620         break;
0621     case METRICS_AVERAGE_GFXACTIVITY:
0622         *value = metrics->AverageGfxActivity;
0623         break;
0624     case METRICS_AVERAGE_MEMACTIVITY:
0625         *value = metrics->AverageUclkActivity;
0626         break;
0627     case METRICS_AVERAGE_SOCKETPOWER:
0628         /* Valid power data is available only from primary die */
0629         *value = aldebaran_is_primary(smu) ?
0630                  metrics->AverageSocketPower << 8 :
0631                  0;
0632         break;
0633     case METRICS_TEMPERATURE_EDGE:
0634         *value = metrics->TemperatureEdge *
0635             SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
0636         break;
0637     case METRICS_TEMPERATURE_HOTSPOT:
0638         *value = metrics->TemperatureHotspot *
0639             SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
0640         break;
0641     case METRICS_TEMPERATURE_MEM:
0642         *value = metrics->TemperatureHBM *
0643             SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
0644         break;
0645     case METRICS_TEMPERATURE_VRGFX:
0646         *value = metrics->TemperatureVrGfx *
0647             SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
0648         break;
0649     case METRICS_TEMPERATURE_VRSOC:
0650         *value = metrics->TemperatureVrSoc *
0651             SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
0652         break;
0653     case METRICS_TEMPERATURE_VRMEM:
0654         *value = metrics->TemperatureVrMem *
0655             SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
0656         break;
0657     case METRICS_THROTTLER_STATUS:
0658         *value = metrics->ThrottlerStatus;
0659         break;
0660     case METRICS_UNIQUE_ID_UPPER32:
0661         *value = metrics->PublicSerialNumUpper32;
0662         break;
0663     case METRICS_UNIQUE_ID_LOWER32:
0664         *value = metrics->PublicSerialNumLower32;
0665         break;
0666     default:
0667         *value = UINT_MAX;
0668         break;
0669     }
0670 
0671     return ret;
0672 }
0673 
0674 static int aldebaran_get_current_clk_freq_by_table(struct smu_context *smu,
0675                            enum smu_clk_type clk_type,
0676                            uint32_t *value)
0677 {
0678     MetricsMember_t member_type;
0679     int clk_id = 0;
0680 
0681     if (!value)
0682         return -EINVAL;
0683 
0684     clk_id = smu_cmn_to_asic_specific_index(smu,
0685                         CMN2ASIC_MAPPING_CLK,
0686                         clk_type);
0687     if (clk_id < 0)
0688         return -EINVAL;
0689 
0690     switch (clk_id) {
0691     case PPCLK_GFXCLK:
0692         /*
0693          * CurrClock[clk_id] can provide accurate
0694          *   output only when the dpm feature is enabled.
0695          * We can use Average_* for dpm disabled case.
0696          *   But this is available for gfxclk/uclk/socclk/vclk/dclk.
0697          */
0698         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT))
0699             member_type = METRICS_CURR_GFXCLK;
0700         else
0701             member_type = METRICS_AVERAGE_GFXCLK;
0702         break;
0703     case PPCLK_UCLK:
0704         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT))
0705             member_type = METRICS_CURR_UCLK;
0706         else
0707             member_type = METRICS_AVERAGE_UCLK;
0708         break;
0709     case PPCLK_SOCCLK:
0710         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT))
0711             member_type = METRICS_CURR_SOCCLK;
0712         else
0713             member_type = METRICS_AVERAGE_SOCCLK;
0714         break;
0715     case PPCLK_VCLK:
0716         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT))
0717             member_type = METRICS_CURR_VCLK;
0718         else
0719             member_type = METRICS_AVERAGE_VCLK;
0720         break;
0721     case PPCLK_DCLK:
0722         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT))
0723             member_type = METRICS_CURR_DCLK;
0724         else
0725             member_type = METRICS_AVERAGE_DCLK;
0726         break;
0727     case PPCLK_FCLK:
0728         member_type = METRICS_CURR_FCLK;
0729         break;
0730     default:
0731         return -EINVAL;
0732     }
0733 
0734     return aldebaran_get_smu_metrics_data(smu,
0735                           member_type,
0736                           value);
0737 }
0738 
0739 static int aldebaran_print_clk_levels(struct smu_context *smu,
0740                       enum smu_clk_type type, char *buf)
0741 {
0742     int i, now, size = 0;
0743     int ret = 0;
0744     struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
0745     struct pp_clock_levels_with_latency clocks;
0746     struct smu_13_0_dpm_table *single_dpm_table;
0747     struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
0748     struct smu_13_0_dpm_context *dpm_context = NULL;
0749     int display_levels;
0750     uint32_t freq_values[3] = {0};
0751     uint32_t min_clk, max_clk;
0752 
0753     smu_cmn_get_sysfs_buf(&buf, &size);
0754 
0755     if (amdgpu_ras_intr_triggered()) {
0756         size += sysfs_emit_at(buf, size, "unavailable\n");
0757         return size;
0758     }
0759 
0760     dpm_context = smu_dpm->dpm_context;
0761 
0762     switch (type) {
0763 
0764     case SMU_OD_SCLK:
0765         size += sysfs_emit_at(buf, size, "%s:\n", "GFXCLK");
0766         fallthrough;
0767     case SMU_SCLK:
0768         ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_GFXCLK, &now);
0769         if (ret) {
0770             dev_err(smu->adev->dev, "Attempt to get current gfx clk Failed!");
0771             return ret;
0772         }
0773 
0774         single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
0775         ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
0776         if (ret) {
0777             dev_err(smu->adev->dev, "Attempt to get gfx clk levels Failed!");
0778             return ret;
0779         }
0780 
0781         display_levels = (clocks.num_levels == 1) ? 1 : 2;
0782 
0783         min_clk = pstate_table->gfxclk_pstate.curr.min;
0784         max_clk = pstate_table->gfxclk_pstate.curr.max;
0785 
0786         freq_values[0] = min_clk;
0787         freq_values[1] = max_clk;
0788 
0789         /* fine-grained dpm has only 2 levels */
0790         if (now > min_clk && now < max_clk) {
0791             display_levels++;
0792             freq_values[2] = max_clk;
0793             freq_values[1] = now;
0794         }
0795 
0796         for (i = 0; i < display_levels; i++)
0797             size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i,
0798                 freq_values[i],
0799                 (display_levels == 1) ?
0800                     "*" :
0801                     (aldebaran_freqs_in_same_level(
0802                          freq_values[i], now) ?
0803                          "*" :
0804                          ""));
0805 
0806         break;
0807 
0808     case SMU_OD_MCLK:
0809         size += sysfs_emit_at(buf, size, "%s:\n", "MCLK");
0810         fallthrough;
0811     case SMU_MCLK:
0812         ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_UCLK, &now);
0813         if (ret) {
0814             dev_err(smu->adev->dev, "Attempt to get current mclk Failed!");
0815             return ret;
0816         }
0817 
0818         single_dpm_table = &(dpm_context->dpm_tables.uclk_table);
0819         ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
0820         if (ret) {
0821             dev_err(smu->adev->dev, "Attempt to get memory clk levels Failed!");
0822             return ret;
0823         }
0824 
0825         for (i = 0; i < clocks.num_levels; i++)
0826             size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
0827                     i, clocks.data[i].clocks_in_khz / 1000,
0828                     (clocks.num_levels == 1) ? "*" :
0829                     (aldebaran_freqs_in_same_level(
0830                                        clocks.data[i].clocks_in_khz / 1000,
0831                                        now) ? "*" : ""));
0832         break;
0833 
0834     case SMU_SOCCLK:
0835         ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_SOCCLK, &now);
0836         if (ret) {
0837             dev_err(smu->adev->dev, "Attempt to get current socclk Failed!");
0838             return ret;
0839         }
0840 
0841         single_dpm_table = &(dpm_context->dpm_tables.soc_table);
0842         ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
0843         if (ret) {
0844             dev_err(smu->adev->dev, "Attempt to get socclk levels Failed!");
0845             return ret;
0846         }
0847 
0848         for (i = 0; i < clocks.num_levels; i++)
0849             size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
0850                     i, clocks.data[i].clocks_in_khz / 1000,
0851                     (clocks.num_levels == 1) ? "*" :
0852                     (aldebaran_freqs_in_same_level(
0853                                        clocks.data[i].clocks_in_khz / 1000,
0854                                        now) ? "*" : ""));
0855         break;
0856 
0857     case SMU_FCLK:
0858         ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_FCLK, &now);
0859         if (ret) {
0860             dev_err(smu->adev->dev, "Attempt to get current fclk Failed!");
0861             return ret;
0862         }
0863 
0864         single_dpm_table = &(dpm_context->dpm_tables.fclk_table);
0865         ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
0866         if (ret) {
0867             dev_err(smu->adev->dev, "Attempt to get fclk levels Failed!");
0868             return ret;
0869         }
0870 
0871         for (i = 0; i < single_dpm_table->count; i++)
0872             size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
0873                     i, single_dpm_table->dpm_levels[i].value,
0874                     (clocks.num_levels == 1) ? "*" :
0875                     (aldebaran_freqs_in_same_level(
0876                                        clocks.data[i].clocks_in_khz / 1000,
0877                                        now) ? "*" : ""));
0878         break;
0879 
0880     case SMU_VCLK:
0881         ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_VCLK, &now);
0882         if (ret) {
0883             dev_err(smu->adev->dev, "Attempt to get current vclk Failed!");
0884             return ret;
0885         }
0886 
0887         single_dpm_table = &(dpm_context->dpm_tables.vclk_table);
0888         ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
0889         if (ret) {
0890             dev_err(smu->adev->dev, "Attempt to get vclk levels Failed!");
0891             return ret;
0892         }
0893 
0894         for (i = 0; i < single_dpm_table->count; i++)
0895             size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
0896                     i, single_dpm_table->dpm_levels[i].value,
0897                     (clocks.num_levels == 1) ? "*" :
0898                     (aldebaran_freqs_in_same_level(
0899                                        clocks.data[i].clocks_in_khz / 1000,
0900                                        now) ? "*" : ""));
0901         break;
0902 
0903     case SMU_DCLK:
0904         ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_DCLK, &now);
0905         if (ret) {
0906             dev_err(smu->adev->dev, "Attempt to get current dclk Failed!");
0907             return ret;
0908         }
0909 
0910         single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
0911         ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table);
0912         if (ret) {
0913             dev_err(smu->adev->dev, "Attempt to get dclk levels Failed!");
0914             return ret;
0915         }
0916 
0917         for (i = 0; i < single_dpm_table->count; i++)
0918             size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
0919                     i, single_dpm_table->dpm_levels[i].value,
0920                     (clocks.num_levels == 1) ? "*" :
0921                     (aldebaran_freqs_in_same_level(
0922                                        clocks.data[i].clocks_in_khz / 1000,
0923                                        now) ? "*" : ""));
0924         break;
0925 
0926     default:
0927         break;
0928     }
0929 
0930     return size;
0931 }
0932 
0933 static int aldebaran_upload_dpm_level(struct smu_context *smu,
0934                       bool max,
0935                       uint32_t feature_mask,
0936                       uint32_t level)
0937 {
0938     struct smu_13_0_dpm_context *dpm_context =
0939         smu->smu_dpm.dpm_context;
0940     uint32_t freq;
0941     int ret = 0;
0942 
0943     if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT) &&
0944         (feature_mask & FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT))) {
0945         freq = dpm_context->dpm_tables.gfx_table.dpm_levels[level].value;
0946         ret = smu_cmn_send_smc_msg_with_param(smu,
0947                               (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
0948                               (PPCLK_GFXCLK << 16) | (freq & 0xffff),
0949                               NULL);
0950         if (ret) {
0951             dev_err(smu->adev->dev, "Failed to set soft %s gfxclk !\n",
0952                 max ? "max" : "min");
0953             return ret;
0954         }
0955     }
0956 
0957     if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
0958         (feature_mask & FEATURE_MASK(FEATURE_DPM_UCLK_BIT))) {
0959         freq = dpm_context->dpm_tables.uclk_table.dpm_levels[level].value;
0960         ret = smu_cmn_send_smc_msg_with_param(smu,
0961                               (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
0962                               (PPCLK_UCLK << 16) | (freq & 0xffff),
0963                               NULL);
0964         if (ret) {
0965             dev_err(smu->adev->dev, "Failed to set soft %s memclk !\n",
0966                 max ? "max" : "min");
0967             return ret;
0968         }
0969     }
0970 
0971     if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT) &&
0972         (feature_mask & FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT))) {
0973         freq = dpm_context->dpm_tables.soc_table.dpm_levels[level].value;
0974         ret = smu_cmn_send_smc_msg_with_param(smu,
0975                               (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
0976                               (PPCLK_SOCCLK << 16) | (freq & 0xffff),
0977                               NULL);
0978         if (ret) {
0979             dev_err(smu->adev->dev, "Failed to set soft %s socclk !\n",
0980                 max ? "max" : "min");
0981             return ret;
0982         }
0983     }
0984 
0985     return ret;
0986 }
0987 
0988 static int aldebaran_force_clk_levels(struct smu_context *smu,
0989                       enum smu_clk_type type, uint32_t mask)
0990 {
0991     struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
0992     struct smu_13_0_dpm_table *single_dpm_table = NULL;
0993     uint32_t soft_min_level, soft_max_level;
0994     int ret = 0;
0995 
0996     soft_min_level = mask ? (ffs(mask) - 1) : 0;
0997     soft_max_level = mask ? (fls(mask) - 1) : 0;
0998 
0999     switch (type) {
1000     case SMU_SCLK:
1001         single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
1002         if (soft_max_level >= single_dpm_table->count) {
1003             dev_err(smu->adev->dev, "Clock level specified %d is over max allowed %d\n",
1004                 soft_max_level, single_dpm_table->count - 1);
1005             ret = -EINVAL;
1006             break;
1007         }
1008 
1009         ret = aldebaran_upload_dpm_level(smu,
1010                          false,
1011                          FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT),
1012                          soft_min_level);
1013         if (ret) {
1014             dev_err(smu->adev->dev, "Failed to upload boot level to lowest!\n");
1015             break;
1016         }
1017 
1018         ret = aldebaran_upload_dpm_level(smu,
1019                          true,
1020                          FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT),
1021                          soft_max_level);
1022         if (ret)
1023             dev_err(smu->adev->dev, "Failed to upload dpm max level to highest!\n");
1024 
1025         break;
1026 
1027     case SMU_MCLK:
1028     case SMU_SOCCLK:
1029     case SMU_FCLK:
1030         /*
1031          * Should not arrive here since aldebaran does not
1032          * support mclk/socclk/fclk softmin/softmax settings
1033          */
1034         ret = -EINVAL;
1035         break;
1036 
1037     default:
1038         break;
1039     }
1040 
1041     return ret;
1042 }
1043 
1044 static int aldebaran_get_thermal_temperature_range(struct smu_context *smu,
1045                            struct smu_temperature_range *range)
1046 {
1047     struct smu_table_context *table_context = &smu->smu_table;
1048     struct smu_13_0_powerplay_table *powerplay_table =
1049         table_context->power_play_table;
1050     PPTable_t *pptable = smu->smu_table.driver_pptable;
1051 
1052     if (!range)
1053         return -EINVAL;
1054 
1055     memcpy(range, &smu13_thermal_policy[0], sizeof(struct smu_temperature_range));
1056 
1057     range->hotspot_crit_max = pptable->ThotspotLimit *
1058         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1059     range->hotspot_emergency_max = (pptable->ThotspotLimit + CTF_OFFSET_HOTSPOT) *
1060         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1061     range->mem_crit_max = pptable->TmemLimit *
1062         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1063     range->mem_emergency_max = (pptable->TmemLimit + CTF_OFFSET_MEM)*
1064         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1065     range->software_shutdown_temp = powerplay_table->software_shutdown_temp;
1066 
1067     return 0;
1068 }
1069 
1070 static int aldebaran_get_current_activity_percent(struct smu_context *smu,
1071                           enum amd_pp_sensors sensor,
1072                           uint32_t *value)
1073 {
1074     int ret = 0;
1075 
1076     if (!value)
1077         return -EINVAL;
1078 
1079     switch (sensor) {
1080     case AMDGPU_PP_SENSOR_GPU_LOAD:
1081         ret = aldebaran_get_smu_metrics_data(smu,
1082                              METRICS_AVERAGE_GFXACTIVITY,
1083                              value);
1084         break;
1085     case AMDGPU_PP_SENSOR_MEM_LOAD:
1086         ret = aldebaran_get_smu_metrics_data(smu,
1087                              METRICS_AVERAGE_MEMACTIVITY,
1088                              value);
1089         break;
1090     default:
1091         dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n");
1092         return -EINVAL;
1093     }
1094 
1095     return ret;
1096 }
1097 
1098 static int aldebaran_get_gpu_power(struct smu_context *smu, uint32_t *value)
1099 {
1100     if (!value)
1101         return -EINVAL;
1102 
1103     return aldebaran_get_smu_metrics_data(smu,
1104                           METRICS_AVERAGE_SOCKETPOWER,
1105                           value);
1106 }
1107 
1108 static int aldebaran_thermal_get_temperature(struct smu_context *smu,
1109                          enum amd_pp_sensors sensor,
1110                          uint32_t *value)
1111 {
1112     int ret = 0;
1113 
1114     if (!value)
1115         return -EINVAL;
1116 
1117     switch (sensor) {
1118     case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1119         ret = aldebaran_get_smu_metrics_data(smu,
1120                              METRICS_TEMPERATURE_HOTSPOT,
1121                              value);
1122         break;
1123     case AMDGPU_PP_SENSOR_EDGE_TEMP:
1124         ret = aldebaran_get_smu_metrics_data(smu,
1125                              METRICS_TEMPERATURE_EDGE,
1126                              value);
1127         break;
1128     case AMDGPU_PP_SENSOR_MEM_TEMP:
1129         ret = aldebaran_get_smu_metrics_data(smu,
1130                              METRICS_TEMPERATURE_MEM,
1131                              value);
1132         break;
1133     default:
1134         dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n");
1135         return -EINVAL;
1136     }
1137 
1138     return ret;
1139 }
1140 
1141 static int aldebaran_read_sensor(struct smu_context *smu,
1142                  enum amd_pp_sensors sensor,
1143                  void *data, uint32_t *size)
1144 {
1145     int ret = 0;
1146 
1147     if (amdgpu_ras_intr_triggered())
1148         return 0;
1149 
1150     if (!data || !size)
1151         return -EINVAL;
1152 
1153     switch (sensor) {
1154     case AMDGPU_PP_SENSOR_MEM_LOAD:
1155     case AMDGPU_PP_SENSOR_GPU_LOAD:
1156         ret = aldebaran_get_current_activity_percent(smu,
1157                                  sensor,
1158                                  (uint32_t *)data);
1159         *size = 4;
1160         break;
1161     case AMDGPU_PP_SENSOR_GPU_POWER:
1162         ret = aldebaran_get_gpu_power(smu, (uint32_t *)data);
1163         *size = 4;
1164         break;
1165     case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1166     case AMDGPU_PP_SENSOR_EDGE_TEMP:
1167     case AMDGPU_PP_SENSOR_MEM_TEMP:
1168         ret = aldebaran_thermal_get_temperature(smu, sensor,
1169                             (uint32_t *)data);
1170         *size = 4;
1171         break;
1172     case AMDGPU_PP_SENSOR_GFX_MCLK:
1173         ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data);
1174         /* the output clock frequency in 10K unit */
1175         *(uint32_t *)data *= 100;
1176         *size = 4;
1177         break;
1178     case AMDGPU_PP_SENSOR_GFX_SCLK:
1179         ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data);
1180         *(uint32_t *)data *= 100;
1181         *size = 4;
1182         break;
1183     case AMDGPU_PP_SENSOR_VDDGFX:
1184         ret = smu_v13_0_get_gfx_vdd(smu, (uint32_t *)data);
1185         *size = 4;
1186         break;
1187     default:
1188         ret = -EOPNOTSUPP;
1189         break;
1190     }
1191 
1192     return ret;
1193 }
1194 
1195 static int aldebaran_get_power_limit(struct smu_context *smu,
1196                      uint32_t *current_power_limit,
1197                      uint32_t *default_power_limit,
1198                      uint32_t *max_power_limit)
1199 {
1200     PPTable_t *pptable = smu->smu_table.driver_pptable;
1201     uint32_t power_limit = 0;
1202     int ret;
1203 
1204     if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
1205         if (current_power_limit)
1206             *current_power_limit = 0;
1207         if (default_power_limit)
1208             *default_power_limit = 0;
1209         if (max_power_limit)
1210             *max_power_limit = 0;
1211 
1212         dev_warn(smu->adev->dev,
1213             "PPT feature is not enabled, power values can't be fetched.");
1214 
1215         return 0;
1216     }
1217 
1218     /* Valid power data is available only from primary die.
1219      * For secondary die show the value as 0.
1220      */
1221     if (aldebaran_is_primary(smu)) {
1222         ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetPptLimit,
1223                        &power_limit);
1224 
1225         if (ret) {
1226             /* the last hope to figure out the ppt limit */
1227             if (!pptable) {
1228                 dev_err(smu->adev->dev,
1229                     "Cannot get PPT limit due to pptable missing!");
1230                 return -EINVAL;
1231             }
1232             power_limit = pptable->PptLimit;
1233         }
1234     }
1235 
1236     if (current_power_limit)
1237         *current_power_limit = power_limit;
1238     if (default_power_limit)
1239         *default_power_limit = power_limit;
1240 
1241     if (max_power_limit) {
1242         if (pptable)
1243             *max_power_limit = pptable->PptLimit;
1244     }
1245 
1246     return 0;
1247 }
1248 
1249 static int aldebaran_set_power_limit(struct smu_context *smu,
1250                      enum smu_ppt_limit_type limit_type,
1251                      uint32_t limit)
1252 {
1253     /* Power limit can be set only through primary die */
1254     if (aldebaran_is_primary(smu))
1255         return smu_v13_0_set_power_limit(smu, limit_type, limit);
1256 
1257     return -EINVAL;
1258 }
1259 
1260 static int aldebaran_system_features_control(struct  smu_context *smu, bool enable)
1261 {
1262     int ret;
1263 
1264     ret = smu_v13_0_system_features_control(smu, enable);
1265     if (!ret && enable)
1266         ret = aldebaran_run_btc(smu);
1267 
1268     return ret;
1269 }
1270 
1271 static int aldebaran_set_performance_level(struct smu_context *smu,
1272                        enum amd_dpm_forced_level level)
1273 {
1274     struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
1275     struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1276     struct smu_13_0_dpm_table *gfx_table =
1277         &dpm_context->dpm_tables.gfx_table;
1278     struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1279 
1280     /* Disable determinism if switching to another mode */
1281     if ((smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) &&
1282         (level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)) {
1283         smu_cmn_send_smc_msg(smu, SMU_MSG_DisableDeterminism, NULL);
1284         pstate_table->gfxclk_pstate.curr.max = gfx_table->max;
1285     }
1286 
1287     switch (level) {
1288 
1289     case AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM:
1290         return 0;
1291 
1292     case AMD_DPM_FORCED_LEVEL_HIGH:
1293     case AMD_DPM_FORCED_LEVEL_LOW:
1294     case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1295     case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1296     case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1297     case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1298     default:
1299         break;
1300     }
1301 
1302     return smu_v13_0_set_performance_level(smu, level);
1303 }
1304 
1305 static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu,
1306                       enum smu_clk_type clk_type,
1307                       uint32_t min,
1308                       uint32_t max)
1309 {
1310     struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
1311     struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1312     struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1313     struct amdgpu_device *adev = smu->adev;
1314     uint32_t min_clk;
1315     uint32_t max_clk;
1316     int ret = 0;
1317 
1318     if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK)
1319         return -EINVAL;
1320 
1321     if ((smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
1322             && (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM))
1323         return -EINVAL;
1324 
1325     if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
1326         if (min >= max) {
1327             dev_err(smu->adev->dev,
1328                 "Minimum GFX clk should be less than the maximum allowed clock\n");
1329             return -EINVAL;
1330         }
1331 
1332         if ((min == pstate_table->gfxclk_pstate.curr.min) &&
1333             (max == pstate_table->gfxclk_pstate.curr.max))
1334             return 0;
1335 
1336         ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK,
1337                                 min, max);
1338         if (!ret) {
1339             pstate_table->gfxclk_pstate.curr.min = min;
1340             pstate_table->gfxclk_pstate.curr.max = max;
1341         }
1342 
1343         return ret;
1344     }
1345 
1346     if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
1347         if (!max || (max < dpm_context->dpm_tables.gfx_table.min) ||
1348             (max > dpm_context->dpm_tables.gfx_table.max)) {
1349             dev_warn(adev->dev,
1350                     "Invalid max frequency %d MHz specified for determinism\n", max);
1351             return -EINVAL;
1352         }
1353 
1354         /* Restore default min/max clocks and enable determinism */
1355         min_clk = dpm_context->dpm_tables.gfx_table.min;
1356         max_clk = dpm_context->dpm_tables.gfx_table.max;
1357         ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
1358         if (!ret) {
1359             usleep_range(500, 1000);
1360             ret = smu_cmn_send_smc_msg_with_param(smu,
1361                     SMU_MSG_EnableDeterminism,
1362                     max, NULL);
1363             if (ret) {
1364                 dev_err(adev->dev,
1365                         "Failed to enable determinism at GFX clock %d MHz\n", max);
1366             } else {
1367                 pstate_table->gfxclk_pstate.curr.min = min_clk;
1368                 pstate_table->gfxclk_pstate.curr.max = max;
1369             }
1370         }
1371     }
1372 
1373     return ret;
1374 }
1375 
1376 static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type,
1377                             long input[], uint32_t size)
1378 {
1379     struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
1380     struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1381     struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1382     uint32_t min_clk;
1383     uint32_t max_clk;
1384     int ret = 0;
1385 
1386     /* Only allowed in manual or determinism mode */
1387     if ((smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
1388             && (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM))
1389         return -EINVAL;
1390 
1391     switch (type) {
1392     case PP_OD_EDIT_SCLK_VDDC_TABLE:
1393         if (size != 2) {
1394             dev_err(smu->adev->dev, "Input parameter number not correct\n");
1395             return -EINVAL;
1396         }
1397 
1398         if (input[0] == 0) {
1399             if (input[1] < dpm_context->dpm_tables.gfx_table.min) {
1400                 dev_warn(smu->adev->dev, "Minimum GFX clk (%ld) MHz specified is less than the minimum allowed (%d) MHz\n",
1401                     input[1], dpm_context->dpm_tables.gfx_table.min);
1402                 pstate_table->gfxclk_pstate.custom.min =
1403                     pstate_table->gfxclk_pstate.curr.min;
1404                 return -EINVAL;
1405             }
1406 
1407             pstate_table->gfxclk_pstate.custom.min = input[1];
1408         } else if (input[0] == 1) {
1409             if (input[1] > dpm_context->dpm_tables.gfx_table.max) {
1410                 dev_warn(smu->adev->dev, "Maximum GFX clk (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n",
1411                     input[1], dpm_context->dpm_tables.gfx_table.max);
1412                 pstate_table->gfxclk_pstate.custom.max =
1413                     pstate_table->gfxclk_pstate.curr.max;
1414                 return -EINVAL;
1415             }
1416 
1417             pstate_table->gfxclk_pstate.custom.max = input[1];
1418         } else {
1419             return -EINVAL;
1420         }
1421         break;
1422     case PP_OD_RESTORE_DEFAULT_TABLE:
1423         if (size != 0) {
1424             dev_err(smu->adev->dev, "Input parameter number not correct\n");
1425             return -EINVAL;
1426         } else {
1427             /* Use the default frequencies for manual and determinism mode */
1428             min_clk = dpm_context->dpm_tables.gfx_table.min;
1429             max_clk = dpm_context->dpm_tables.gfx_table.max;
1430 
1431             return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
1432         }
1433         break;
1434     case PP_OD_COMMIT_DPM_TABLE:
1435         if (size != 0) {
1436             dev_err(smu->adev->dev, "Input parameter number not correct\n");
1437             return -EINVAL;
1438         } else {
1439             if (!pstate_table->gfxclk_pstate.custom.min)
1440                 pstate_table->gfxclk_pstate.custom.min =
1441                     pstate_table->gfxclk_pstate.curr.min;
1442 
1443             if (!pstate_table->gfxclk_pstate.custom.max)
1444                 pstate_table->gfxclk_pstate.custom.max =
1445                     pstate_table->gfxclk_pstate.curr.max;
1446 
1447             min_clk = pstate_table->gfxclk_pstate.custom.min;
1448             max_clk = pstate_table->gfxclk_pstate.custom.max;
1449 
1450             return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
1451         }
1452         break;
1453     default:
1454         return -ENOSYS;
1455     }
1456 
1457     return ret;
1458 }
1459 
1460 static bool aldebaran_is_dpm_running(struct smu_context *smu)
1461 {
1462     int ret;
1463     uint64_t feature_enabled;
1464 
1465     ret = smu_cmn_get_enabled_mask(smu, &feature_enabled);
1466     if (ret)
1467         return false;
1468     return !!(feature_enabled & SMC_DPM_FEATURE);
1469 }
1470 
1471 static int aldebaran_i2c_xfer(struct i2c_adapter *i2c_adap,
1472                   struct i2c_msg *msg, int num_msgs)
1473 {
1474     struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(i2c_adap);
1475     struct amdgpu_device *adev = smu_i2c->adev;
1476     struct smu_context *smu = adev->powerplay.pp_handle;
1477     struct smu_table_context *smu_table = &smu->smu_table;
1478     struct smu_table *table = &smu_table->driver_table;
1479     SwI2cRequest_t *req, *res = (SwI2cRequest_t *)table->cpu_addr;
1480     int i, j, r, c;
1481     u16 dir;
1482 
1483     if (!adev->pm.dpm_enabled)
1484         return -EBUSY;
1485 
1486     req = kzalloc(sizeof(*req), GFP_KERNEL);
1487     if (!req)
1488         return -ENOMEM;
1489 
1490     req->I2CcontrollerPort = smu_i2c->port;
1491     req->I2CSpeed = I2C_SPEED_FAST_400K;
1492     req->SlaveAddress = msg[0].addr << 1; /* wants an 8-bit address */
1493     dir = msg[0].flags & I2C_M_RD;
1494 
1495     for (c = i = 0; i < num_msgs; i++) {
1496         for (j = 0; j < msg[i].len; j++, c++) {
1497             SwI2cCmd_t *cmd = &req->SwI2cCmds[c];
1498 
1499             if (!(msg[i].flags & I2C_M_RD)) {
1500                 /* write */
1501                 cmd->CmdConfig |= CMDCONFIG_READWRITE_MASK;
1502                 cmd->ReadWriteData = msg[i].buf[j];
1503             }
1504 
1505             if ((dir ^ msg[i].flags) & I2C_M_RD) {
1506                 /* The direction changes.
1507                  */
1508                 dir = msg[i].flags & I2C_M_RD;
1509                 cmd->CmdConfig |= CMDCONFIG_RESTART_MASK;
1510             }
1511 
1512             req->NumCmds++;
1513 
1514             /*
1515              * Insert STOP if we are at the last byte of either last
1516              * message for the transaction or the client explicitly
1517              * requires a STOP at this particular message.
1518              */
1519             if ((j == msg[i].len - 1) &&
1520                 ((i == num_msgs - 1) || (msg[i].flags & I2C_M_STOP))) {
1521                 cmd->CmdConfig &= ~CMDCONFIG_RESTART_MASK;
1522                 cmd->CmdConfig |= CMDCONFIG_STOP_MASK;
1523             }
1524         }
1525     }
1526     mutex_lock(&adev->pm.mutex);
1527     r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true);
1528     mutex_unlock(&adev->pm.mutex);
1529     if (r)
1530         goto fail;
1531 
1532     for (c = i = 0; i < num_msgs; i++) {
1533         if (!(msg[i].flags & I2C_M_RD)) {
1534             c += msg[i].len;
1535             continue;
1536         }
1537         for (j = 0; j < msg[i].len; j++, c++) {
1538             SwI2cCmd_t *cmd = &res->SwI2cCmds[c];
1539 
1540             msg[i].buf[j] = cmd->ReadWriteData;
1541         }
1542     }
1543     r = num_msgs;
1544 fail:
1545     kfree(req);
1546     return r;
1547 }
1548 
1549 static u32 aldebaran_i2c_func(struct i2c_adapter *adap)
1550 {
1551     return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
1552 }
1553 
1554 
1555 static const struct i2c_algorithm aldebaran_i2c_algo = {
1556     .master_xfer = aldebaran_i2c_xfer,
1557     .functionality = aldebaran_i2c_func,
1558 };
1559 
1560 static const struct i2c_adapter_quirks aldebaran_i2c_control_quirks = {
1561     .flags = I2C_AQ_COMB | I2C_AQ_COMB_SAME_ADDR | I2C_AQ_NO_ZERO_LEN,
1562     .max_read_len  = MAX_SW_I2C_COMMANDS,
1563     .max_write_len = MAX_SW_I2C_COMMANDS,
1564     .max_comb_1st_msg_len = 2,
1565     .max_comb_2nd_msg_len = MAX_SW_I2C_COMMANDS - 2,
1566 };
1567 
1568 static int aldebaran_i2c_control_init(struct smu_context *smu)
1569 {
1570     struct amdgpu_device *adev = smu->adev;
1571     struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[0];
1572     struct i2c_adapter *control = &smu_i2c->adapter;
1573     int res;
1574 
1575     smu_i2c->adev = adev;
1576     smu_i2c->port = 0;
1577     mutex_init(&smu_i2c->mutex);
1578     control->owner = THIS_MODULE;
1579     control->class = I2C_CLASS_SPD;
1580     control->dev.parent = &adev->pdev->dev;
1581     control->algo = &aldebaran_i2c_algo;
1582     snprintf(control->name, sizeof(control->name), "AMDGPU SMU 0");
1583     control->quirks = &aldebaran_i2c_control_quirks;
1584     i2c_set_adapdata(control, smu_i2c);
1585 
1586     res = i2c_add_adapter(control);
1587     if (res) {
1588         DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
1589         goto Out_err;
1590     }
1591 
1592     adev->pm.ras_eeprom_i2c_bus = &adev->pm.smu_i2c[0].adapter;
1593     adev->pm.fru_eeprom_i2c_bus = &adev->pm.smu_i2c[0].adapter;
1594 
1595     return 0;
1596 Out_err:
1597     i2c_del_adapter(control);
1598 
1599     return res;
1600 }
1601 
1602 static void aldebaran_i2c_control_fini(struct smu_context *smu)
1603 {
1604     struct amdgpu_device *adev = smu->adev;
1605     int i;
1606 
1607     for (i = 0; i < MAX_SMU_I2C_BUSES; i++) {
1608         struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[i];
1609         struct i2c_adapter *control = &smu_i2c->adapter;
1610 
1611         i2c_del_adapter(control);
1612     }
1613     adev->pm.ras_eeprom_i2c_bus = NULL;
1614     adev->pm.fru_eeprom_i2c_bus = NULL;
1615 }
1616 
1617 static void aldebaran_get_unique_id(struct smu_context *smu)
1618 {
1619     struct amdgpu_device *adev = smu->adev;
1620     uint32_t upper32 = 0, lower32 = 0;
1621 
1622     if (aldebaran_get_smu_metrics_data(smu, METRICS_UNIQUE_ID_UPPER32, &upper32))
1623         goto out;
1624     if (aldebaran_get_smu_metrics_data(smu, METRICS_UNIQUE_ID_LOWER32, &lower32))
1625         goto out;
1626 
1627 out:
1628     adev->unique_id = ((uint64_t)upper32 << 32) | lower32;
1629     if (adev->serial[0] == '\0')
1630         sprintf(adev->serial, "%016llx", adev->unique_id);
1631 }
1632 
1633 static bool aldebaran_is_baco_supported(struct smu_context *smu)
1634 {
1635     /* aldebaran is not support baco */
1636 
1637     return false;
1638 }
1639 
1640 static int aldebaran_set_df_cstate(struct smu_context *smu,
1641                    enum pp_df_cstate state)
1642 {
1643     return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state, NULL);
1644 }
1645 
1646 static int aldebaran_allow_xgmi_power_down(struct smu_context *smu, bool en)
1647 {
1648     struct amdgpu_device *adev = smu->adev;
1649 
1650     /* The message only works on master die and NACK will be sent
1651        back for other dies, only send it on master die */
1652     if (!adev->smuio.funcs->get_socket_id(adev) &&
1653         !adev->smuio.funcs->get_die_id(adev))
1654         return smu_cmn_send_smc_msg_with_param(smu,
1655                    SMU_MSG_GmiPwrDnControl,
1656                    en ? 0 : 1,
1657                    NULL);
1658     else
1659         return 0;
1660 }
1661 
1662 static const struct throttling_logging_label {
1663     uint32_t feature_mask;
1664     const char *label;
1665 } logging_label[] = {
1666     {(1U << THROTTLER_TEMP_GPU_BIT), "GPU"},
1667     {(1U << THROTTLER_TEMP_MEM_BIT), "HBM"},
1668     {(1U << THROTTLER_TEMP_VR_GFX_BIT), "VR of GFX rail"},
1669     {(1U << THROTTLER_TEMP_VR_MEM_BIT), "VR of HBM rail"},
1670     {(1U << THROTTLER_TEMP_VR_SOC_BIT), "VR of SOC rail"},
1671 };
1672 static void aldebaran_log_thermal_throttling_event(struct smu_context *smu)
1673 {
1674     int ret;
1675     int throttler_idx, throtting_events = 0, buf_idx = 0;
1676     struct amdgpu_device *adev = smu->adev;
1677     uint32_t throttler_status;
1678     char log_buf[256];
1679 
1680     ret = aldebaran_get_smu_metrics_data(smu,
1681                          METRICS_THROTTLER_STATUS,
1682                          &throttler_status);
1683     if (ret)
1684         return;
1685 
1686     memset(log_buf, 0, sizeof(log_buf));
1687     for (throttler_idx = 0; throttler_idx < ARRAY_SIZE(logging_label);
1688          throttler_idx++) {
1689         if (throttler_status & logging_label[throttler_idx].feature_mask) {
1690             throtting_events++;
1691             buf_idx += snprintf(log_buf + buf_idx,
1692                         sizeof(log_buf) - buf_idx,
1693                         "%s%s",
1694                         throtting_events > 1 ? " and " : "",
1695                         logging_label[throttler_idx].label);
1696             if (buf_idx >= sizeof(log_buf)) {
1697                 dev_err(adev->dev, "buffer overflow!\n");
1698                 log_buf[sizeof(log_buf) - 1] = '\0';
1699                 break;
1700             }
1701         }
1702     }
1703 
1704     dev_warn(adev->dev, "WARN: GPU thermal throttling temperature reached, expect performance decrease. %s.\n",
1705          log_buf);
1706     kgd2kfd_smi_event_throttle(smu->adev->kfd.dev,
1707         smu_cmn_get_indep_throttler_status(throttler_status,
1708                            aldebaran_throttler_map));
1709 }
1710 
1711 static int aldebaran_get_current_pcie_link_speed(struct smu_context *smu)
1712 {
1713     struct amdgpu_device *adev = smu->adev;
1714     uint32_t esm_ctrl;
1715 
1716     /* TODO: confirm this on real target */
1717     esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL);
1718     if ((esm_ctrl >> 15) & 0x1FFFF)
1719         return (((esm_ctrl >> 8) & 0x3F) + 128);
1720 
1721     return smu_v13_0_get_current_pcie_link_speed(smu);
1722 }
1723 
1724 static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
1725                      void **table)
1726 {
1727     struct smu_table_context *smu_table = &smu->smu_table;
1728     struct gpu_metrics_v1_3 *gpu_metrics =
1729         (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
1730     SmuMetrics_t metrics;
1731     int i, ret = 0;
1732 
1733     ret = smu_cmn_get_metrics_table(smu,
1734                     &metrics,
1735                     true);
1736     if (ret)
1737         return ret;
1738 
1739     smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
1740 
1741     gpu_metrics->temperature_edge = metrics.TemperatureEdge;
1742     gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot;
1743     gpu_metrics->temperature_mem = metrics.TemperatureHBM;
1744     gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx;
1745     gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc;
1746     gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem;
1747 
1748     gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity;
1749     gpu_metrics->average_umc_activity = metrics.AverageUclkActivity;
1750     gpu_metrics->average_mm_activity = 0;
1751 
1752     /* Valid power data is available only from primary die */
1753     if (aldebaran_is_primary(smu)) {
1754         gpu_metrics->average_socket_power = metrics.AverageSocketPower;
1755         gpu_metrics->energy_accumulator =
1756             (uint64_t)metrics.EnergyAcc64bitHigh << 32 |
1757             metrics.EnergyAcc64bitLow;
1758     } else {
1759         gpu_metrics->average_socket_power = 0;
1760         gpu_metrics->energy_accumulator = 0;
1761     }
1762 
1763     gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency;
1764     gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency;
1765     gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequency;
1766     gpu_metrics->average_vclk0_frequency = 0;
1767     gpu_metrics->average_dclk0_frequency = 0;
1768 
1769     gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK];
1770     gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK];
1771     gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK];
1772     gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK];
1773     gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
1774 
1775     gpu_metrics->throttle_status = metrics.ThrottlerStatus;
1776     gpu_metrics->indep_throttle_status =
1777             smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
1778                                aldebaran_throttler_map);
1779 
1780     gpu_metrics->current_fan_speed = 0;
1781 
1782     gpu_metrics->pcie_link_width =
1783         smu_v13_0_get_current_pcie_link_width(smu);
1784     gpu_metrics->pcie_link_speed =
1785         aldebaran_get_current_pcie_link_speed(smu);
1786 
1787     gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
1788 
1789     gpu_metrics->gfx_activity_acc = metrics.GfxBusyAcc;
1790     gpu_metrics->mem_activity_acc = metrics.DramBusyAcc;
1791 
1792     for (i = 0; i < NUM_HBM_INSTANCES; i++)
1793         gpu_metrics->temperature_hbm[i] = metrics.TemperatureAllHBM[i];
1794 
1795     gpu_metrics->firmware_timestamp = ((uint64_t)metrics.TimeStampHigh << 32) |
1796                     metrics.TimeStampLow;
1797 
1798     *table = (void *)gpu_metrics;
1799 
1800     return sizeof(struct gpu_metrics_v1_3);
1801 }
1802 
1803 static int aldebaran_check_ecc_table_support(struct smu_context *smu,
1804         int *ecctable_version)
1805 {
1806     uint32_t if_version = 0xff, smu_version = 0xff;
1807     int ret = 0;
1808 
1809     ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version);
1810     if (ret) {
1811         /* return not support if failed get smu_version */
1812         ret = -EOPNOTSUPP;
1813     }
1814 
1815     if (smu_version < SUPPORT_ECCTABLE_SMU_VERSION)
1816         ret = -EOPNOTSUPP;
1817     else if (smu_version >= SUPPORT_ECCTABLE_SMU_VERSION &&
1818             smu_version < SUPPORT_ECCTABLE_V2_SMU_VERSION)
1819         *ecctable_version = 1;
1820     else
1821         *ecctable_version = 2;
1822 
1823     return ret;
1824 }
1825 
1826 static ssize_t aldebaran_get_ecc_info(struct smu_context *smu,
1827                      void *table)
1828 {
1829     struct smu_table_context *smu_table = &smu->smu_table;
1830     EccInfoTable_t *ecc_table = NULL;
1831     struct ecc_info_per_ch *ecc_info_per_channel = NULL;
1832     int i, ret = 0;
1833     int table_version = 0;
1834     struct umc_ecc_info *eccinfo = (struct umc_ecc_info *)table;
1835 
1836     ret = aldebaran_check_ecc_table_support(smu, &table_version);
1837     if (ret)
1838         return ret;
1839 
1840     ret = smu_cmn_update_table(smu,
1841                    SMU_TABLE_ECCINFO,
1842                    0,
1843                    smu_table->ecc_table,
1844                    false);
1845     if (ret) {
1846         dev_info(smu->adev->dev, "Failed to export SMU ecc table!\n");
1847         return ret;
1848     }
1849 
1850     ecc_table = (EccInfoTable_t *)smu_table->ecc_table;
1851 
1852     if (table_version == 1) {
1853         for (i = 0; i < ALDEBARAN_UMC_CHANNEL_NUM; i++) {
1854             ecc_info_per_channel = &(eccinfo->ecc[i]);
1855             ecc_info_per_channel->ce_count_lo_chip =
1856                 ecc_table->EccInfo[i].ce_count_lo_chip;
1857             ecc_info_per_channel->ce_count_hi_chip =
1858                 ecc_table->EccInfo[i].ce_count_hi_chip;
1859             ecc_info_per_channel->mca_umc_status =
1860                 ecc_table->EccInfo[i].mca_umc_status;
1861             ecc_info_per_channel->mca_umc_addr =
1862                 ecc_table->EccInfo[i].mca_umc_addr;
1863         }
1864     } else if (table_version == 2) {
1865         for (i = 0; i < ALDEBARAN_UMC_CHANNEL_NUM; i++) {
1866             ecc_info_per_channel = &(eccinfo->ecc[i]);
1867             ecc_info_per_channel->ce_count_lo_chip =
1868                 ecc_table->EccInfo_V2[i].ce_count_lo_chip;
1869             ecc_info_per_channel->ce_count_hi_chip =
1870                 ecc_table->EccInfo_V2[i].ce_count_hi_chip;
1871             ecc_info_per_channel->mca_umc_status =
1872                 ecc_table->EccInfo_V2[i].mca_umc_status;
1873             ecc_info_per_channel->mca_umc_addr =
1874                 ecc_table->EccInfo_V2[i].mca_umc_addr;
1875             ecc_info_per_channel->mca_ceumc_addr =
1876                 ecc_table->EccInfo_V2[i].mca_ceumc_addr;
1877         }
1878         eccinfo->record_ce_addr_supported = 1;
1879     }
1880 
1881     return ret;
1882 }
1883 
1884 static int aldebaran_mode1_reset(struct smu_context *smu)
1885 {
1886     u32 smu_version, fatal_err, param;
1887     int ret = 0;
1888     struct amdgpu_device *adev = smu->adev;
1889     struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
1890 
1891     fatal_err = 0;
1892     param = SMU_RESET_MODE_1;
1893 
1894     /*
1895     * PM FW support SMU_MSG_GfxDeviceDriverReset from 68.07
1896     */
1897     smu_cmn_get_smc_version(smu, NULL, &smu_version);
1898     if (smu_version < 0x00440700) {
1899         ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL);
1900     }
1901     else {
1902         /* fatal error triggered by ras, PMFW supports the flag
1903            from 68.44.0 */
1904         if ((smu_version >= 0x00442c00) && ras &&
1905             atomic_read(&ras->in_recovery))
1906             fatal_err = 1;
1907 
1908         param |= (fatal_err << 16);
1909         ret = smu_cmn_send_smc_msg_with_param(smu,
1910                     SMU_MSG_GfxDeviceDriverReset, param, NULL);
1911     }
1912 
1913     if (!ret)
1914         msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS);
1915 
1916     return ret;
1917 }
1918 
1919 static int aldebaran_mode2_reset(struct smu_context *smu)
1920 {
1921     u32 smu_version;
1922     int ret = 0, index;
1923     struct amdgpu_device *adev = smu->adev;
1924     int timeout = 10;
1925 
1926     smu_cmn_get_smc_version(smu, NULL, &smu_version);
1927 
1928     index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
1929                         SMU_MSG_GfxDeviceDriverReset);
1930 
1931     mutex_lock(&smu->message_lock);
1932     if (smu_version >= 0x00441400) {
1933         ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index, SMU_RESET_MODE_2);
1934         /* This is similar to FLR, wait till max FLR timeout */
1935         msleep(100);
1936         dev_dbg(smu->adev->dev, "restore config space...\n");
1937         /* Restore the config space saved during init */
1938         amdgpu_device_load_pci_state(adev->pdev);
1939 
1940         dev_dbg(smu->adev->dev, "wait for reset ack\n");
1941         while (ret == -ETIME && timeout)  {
1942             ret = smu_cmn_wait_for_response(smu);
1943             /* Wait a bit more time for getting ACK */
1944             if (ret == -ETIME) {
1945                 --timeout;
1946                 usleep_range(500, 1000);
1947                 continue;
1948             }
1949 
1950             if (ret != 1) {
1951                 dev_err(adev->dev, "failed to send mode2 message \tparam: 0x%08x response %#x\n",
1952                         SMU_RESET_MODE_2, ret);
1953                 goto out;
1954             }
1955         }
1956 
1957     } else {
1958         dev_err(adev->dev, "smu fw 0x%x does not support MSG_GfxDeviceDriverReset MSG\n",
1959                 smu_version);
1960     }
1961 
1962     if (ret == 1)
1963         ret = 0;
1964 out:
1965     mutex_unlock(&smu->message_lock);
1966 
1967     return ret;
1968 }
1969 
1970 static int aldebaran_smu_handle_passthrough_sbr(struct smu_context *smu, bool enable)
1971 {
1972     int ret = 0;
1973     ret =  smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_HeavySBR, enable ? 1 : 0, NULL);
1974 
1975     return ret;
1976 }
1977 
1978 static bool aldebaran_is_mode1_reset_supported(struct smu_context *smu)
1979 {
1980 #if 0
1981     struct amdgpu_device *adev = smu->adev;
1982     u32 smu_version;
1983     uint32_t val;
1984     /**
1985      * PM FW version support mode1 reset from 68.07
1986      */
1987     smu_cmn_get_smc_version(smu, NULL, &smu_version);
1988     if ((smu_version < 0x00440700))
1989         return false;
1990     /**
1991      * mode1 reset relies on PSP, so we should check if
1992      * PSP is alive.
1993      */
1994     val = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81);
1995 
1996     return val != 0x0;
1997 #endif
1998     return true;
1999 }
2000 
2001 static bool aldebaran_is_mode2_reset_supported(struct smu_context *smu)
2002 {
2003     return true;
2004 }
2005 
2006 static int aldebaran_set_mp1_state(struct smu_context *smu,
2007                    enum pp_mp1_state mp1_state)
2008 {
2009     switch (mp1_state) {
2010     case PP_MP1_STATE_UNLOAD:
2011         return smu_cmn_set_mp1_state(smu, mp1_state);
2012     default:
2013         return 0;
2014     }
2015 }
2016 
2017 static int aldebaran_smu_send_hbm_bad_page_num(struct smu_context *smu,
2018         uint32_t size)
2019 {
2020     int ret = 0;
2021 
2022     /* message SMU to update the bad page number on SMUBUS */
2023     ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetNumBadHbmPagesRetired, size, NULL);
2024     if (ret)
2025         dev_err(smu->adev->dev, "[%s] failed to message SMU to update HBM bad pages number\n",
2026                 __func__);
2027 
2028     return ret;
2029 }
2030 
2031 static int aldebaran_check_bad_channel_info_support(struct smu_context *smu)
2032 {
2033     uint32_t if_version = 0xff, smu_version = 0xff;
2034     int ret = 0;
2035 
2036     ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version);
2037     if (ret) {
2038         /* return not support if failed get smu_version */
2039         ret = -EOPNOTSUPP;
2040     }
2041 
2042     if (smu_version < SUPPORT_BAD_CHANNEL_INFO_MSG_VERSION)
2043         ret = -EOPNOTSUPP;
2044 
2045     return ret;
2046 }
2047 
2048 static int aldebaran_send_hbm_bad_channel_flag(struct smu_context *smu,
2049         uint32_t size)
2050 {
2051     int ret = 0;
2052 
2053     ret = aldebaran_check_bad_channel_info_support(smu);
2054     if (ret)
2055         return ret;
2056 
2057     /* message SMU to update the bad channel info on SMUBUS */
2058     ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetBadHBMPagesRetiredFlagsPerChannel, size, NULL);
2059     if (ret)
2060         dev_err(smu->adev->dev, "[%s] failed to message SMU to update HBM bad channel info\n",
2061                 __func__);
2062 
2063     return ret;
2064 }
2065 
2066 static const struct pptable_funcs aldebaran_ppt_funcs = {
2067     /* init dpm */
2068     .get_allowed_feature_mask = aldebaran_get_allowed_feature_mask,
2069     /* dpm/clk tables */
2070     .set_default_dpm_table = aldebaran_set_default_dpm_table,
2071     .populate_umd_state_clk = aldebaran_populate_umd_state_clk,
2072     .get_thermal_temperature_range = aldebaran_get_thermal_temperature_range,
2073     .print_clk_levels = aldebaran_print_clk_levels,
2074     .force_clk_levels = aldebaran_force_clk_levels,
2075     .read_sensor = aldebaran_read_sensor,
2076     .set_performance_level = aldebaran_set_performance_level,
2077     .get_power_limit = aldebaran_get_power_limit,
2078     .is_dpm_running = aldebaran_is_dpm_running,
2079     .get_unique_id = aldebaran_get_unique_id,
2080     .init_microcode = smu_v13_0_init_microcode,
2081     .load_microcode = smu_v13_0_load_microcode,
2082     .fini_microcode = smu_v13_0_fini_microcode,
2083     .init_smc_tables = aldebaran_init_smc_tables,
2084     .fini_smc_tables = smu_v13_0_fini_smc_tables,
2085     .init_power = smu_v13_0_init_power,
2086     .fini_power = smu_v13_0_fini_power,
2087     .check_fw_status = smu_v13_0_check_fw_status,
2088     /* pptable related */
2089     .setup_pptable = aldebaran_setup_pptable,
2090     .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values,
2091     .check_fw_version = smu_v13_0_check_fw_version,
2092     .write_pptable = smu_cmn_write_pptable,
2093     .set_driver_table_location = smu_v13_0_set_driver_table_location,
2094     .set_tool_table_location = smu_v13_0_set_tool_table_location,
2095     .notify_memory_pool_location = smu_v13_0_notify_memory_pool_location,
2096     .system_features_control = aldebaran_system_features_control,
2097     .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
2098     .send_smc_msg = smu_cmn_send_smc_msg,
2099     .get_enabled_mask = smu_cmn_get_enabled_mask,
2100     .feature_is_enabled = smu_cmn_feature_is_enabled,
2101     .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception,
2102     .set_power_limit = aldebaran_set_power_limit,
2103     .init_max_sustainable_clocks = smu_v13_0_init_max_sustainable_clocks,
2104     .enable_thermal_alert = smu_v13_0_enable_thermal_alert,
2105     .disable_thermal_alert = smu_v13_0_disable_thermal_alert,
2106     .set_xgmi_pstate = smu_v13_0_set_xgmi_pstate,
2107     .register_irq_handler = smu_v13_0_register_irq_handler,
2108     .set_azalia_d3_pme = smu_v13_0_set_azalia_d3_pme,
2109     .get_max_sustainable_clocks_by_dc = smu_v13_0_get_max_sustainable_clocks_by_dc,
2110     .baco_is_support= aldebaran_is_baco_supported,
2111     .get_dpm_ultimate_freq = smu_v13_0_get_dpm_ultimate_freq,
2112     .set_soft_freq_limited_range = aldebaran_set_soft_freq_limited_range,
2113     .od_edit_dpm_table = aldebaran_usr_edit_dpm_table,
2114     .set_df_cstate = aldebaran_set_df_cstate,
2115     .allow_xgmi_power_down = aldebaran_allow_xgmi_power_down,
2116     .log_thermal_throttling_event = aldebaran_log_thermal_throttling_event,
2117     .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
2118     .set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
2119     .get_gpu_metrics = aldebaran_get_gpu_metrics,
2120     .mode1_reset_is_support = aldebaran_is_mode1_reset_supported,
2121     .mode2_reset_is_support = aldebaran_is_mode2_reset_supported,
2122     .smu_handle_passthrough_sbr = aldebaran_smu_handle_passthrough_sbr,
2123     .mode1_reset = aldebaran_mode1_reset,
2124     .set_mp1_state = aldebaran_set_mp1_state,
2125     .mode2_reset = aldebaran_mode2_reset,
2126     .wait_for_event = smu_v13_0_wait_for_event,
2127     .i2c_init = aldebaran_i2c_control_init,
2128     .i2c_fini = aldebaran_i2c_control_fini,
2129     .send_hbm_bad_pages_num = aldebaran_smu_send_hbm_bad_page_num,
2130     .get_ecc_info = aldebaran_get_ecc_info,
2131     .send_hbm_bad_channel_flag = aldebaran_send_hbm_bad_channel_flag,
2132 };
2133 
2134 void aldebaran_set_ppt_funcs(struct smu_context *smu)
2135 {
2136     smu->ppt_funcs = &aldebaran_ppt_funcs;
2137     smu->message_map = aldebaran_message_map;
2138     smu->clock_map = aldebaran_clk_map;
2139     smu->feature_map = aldebaran_feature_mask_map;
2140     smu->table_map = aldebaran_table_map;
2141     smu_v13_0_set_smu_mailbox_registers(smu);
2142 }