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 "amdgpu.h"
0027 #include "amdgpu_smu.h"
0028 #include "smu_v12_0_ppsmc.h"
0029 #include "smu12_driver_if.h"
0030 #include "smu_v12_0.h"
0031 #include "renoir_ppt.h"
0032 #include "smu_cmn.h"
0033 
0034 /*
0035  * DO NOT use these for err/warn/info/debug messages.
0036  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
0037  * They are more MGPU friendly.
0038  */
0039 #undef pr_err
0040 #undef pr_warn
0041 #undef pr_info
0042 #undef pr_debug
0043 
0044 #define mmMP1_SMN_C2PMSG_66                                                                            0x0282
0045 #define mmMP1_SMN_C2PMSG_66_BASE_IDX                                                                   0
0046 
0047 #define mmMP1_SMN_C2PMSG_82                                                                            0x0292
0048 #define mmMP1_SMN_C2PMSG_82_BASE_IDX                                                                   0
0049 
0050 #define mmMP1_SMN_C2PMSG_90                                                                            0x029a
0051 #define mmMP1_SMN_C2PMSG_90_BASE_IDX                                                                   0
0052 
0053 static struct cmn2asic_msg_mapping renoir_message_map[SMU_MSG_MAX_COUNT] = {
0054     MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage,                  1),
0055     MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetSmuVersion,                1),
0056     MSG_MAP(GetDriverIfVersion,             PPSMC_MSG_GetDriverIfVersion,           1),
0057     MSG_MAP(PowerUpGfx,                     PPSMC_MSG_PowerUpGfx,                   1),
0058     MSG_MAP(AllowGfxOff,                    PPSMC_MSG_EnableGfxOff,                 1),
0059     MSG_MAP(DisallowGfxOff,                 PPSMC_MSG_DisableGfxOff,                1),
0060     MSG_MAP(PowerDownIspByTile,             PPSMC_MSG_PowerDownIspByTile,           1),
0061     MSG_MAP(PowerUpIspByTile,               PPSMC_MSG_PowerUpIspByTile,             1),
0062     MSG_MAP(PowerDownVcn,                   PPSMC_MSG_PowerDownVcn,                 1),
0063     MSG_MAP(PowerUpVcn,                     PPSMC_MSG_PowerUpVcn,                   1),
0064     MSG_MAP(PowerDownSdma,                  PPSMC_MSG_PowerDownSdma,                1),
0065     MSG_MAP(PowerUpSdma,                    PPSMC_MSG_PowerUpSdma,                  1),
0066     MSG_MAP(SetHardMinIspclkByFreq,         PPSMC_MSG_SetHardMinIspclkByFreq,       1),
0067     MSG_MAP(SetHardMinVcn,                  PPSMC_MSG_SetHardMinVcn,                1),
0068     MSG_MAP(SetAllowFclkSwitch,             PPSMC_MSG_SetAllowFclkSwitch,           1),
0069     MSG_MAP(SetMinVideoGfxclkFreq,          PPSMC_MSG_SetMinVideoGfxclkFreq,        1),
0070     MSG_MAP(ActiveProcessNotify,            PPSMC_MSG_ActiveProcessNotify,          1),
0071     MSG_MAP(SetCustomPolicy,                PPSMC_MSG_SetCustomPolicy,              1),
0072     MSG_MAP(SetVideoFps,                    PPSMC_MSG_SetVideoFps,                  1),
0073     MSG_MAP(NumOfDisplays,                  PPSMC_MSG_SetDisplayCount,              1),
0074     MSG_MAP(QueryPowerLimit,                PPSMC_MSG_QueryPowerLimit,              1),
0075     MSG_MAP(SetDriverDramAddrHigh,          PPSMC_MSG_SetDriverDramAddrHigh,        1),
0076     MSG_MAP(SetDriverDramAddrLow,           PPSMC_MSG_SetDriverDramAddrLow,         1),
0077     MSG_MAP(TransferTableSmu2Dram,          PPSMC_MSG_TransferTableSmu2Dram,        1),
0078     MSG_MAP(TransferTableDram2Smu,          PPSMC_MSG_TransferTableDram2Smu,        1),
0079     MSG_MAP(GfxDeviceDriverReset,           PPSMC_MSG_GfxDeviceDriverReset,         1),
0080     MSG_MAP(SetGfxclkOverdriveByFreqVid,    PPSMC_MSG_SetGfxclkOverdriveByFreqVid,  1),
0081     MSG_MAP(SetHardMinDcfclkByFreq,         PPSMC_MSG_SetHardMinDcfclkByFreq,       1),
0082     MSG_MAP(SetHardMinSocclkByFreq,         PPSMC_MSG_SetHardMinSocclkByFreq,       1),
0083     MSG_MAP(ControlIgpuATS,                 PPSMC_MSG_ControlIgpuATS,               1),
0084     MSG_MAP(SetMinVideoFclkFreq,            PPSMC_MSG_SetMinVideoFclkFreq,          1),
0085     MSG_MAP(SetMinDeepSleepDcfclk,          PPSMC_MSG_SetMinDeepSleepDcfclk,        1),
0086     MSG_MAP(ForcePowerDownGfx,              PPSMC_MSG_ForcePowerDownGfx,            1),
0087     MSG_MAP(SetPhyclkVoltageByFreq,         PPSMC_MSG_SetPhyclkVoltageByFreq,       1),
0088     MSG_MAP(SetDppclkVoltageByFreq,         PPSMC_MSG_SetDppclkVoltageByFreq,       1),
0089     MSG_MAP(SetSoftMinVcn,                  PPSMC_MSG_SetSoftMinVcn,                1),
0090     MSG_MAP(EnablePostCode,                 PPSMC_MSG_EnablePostCode,               1),
0091     MSG_MAP(GetGfxclkFrequency,             PPSMC_MSG_GetGfxclkFrequency,           1),
0092     MSG_MAP(GetFclkFrequency,               PPSMC_MSG_GetFclkFrequency,             1),
0093     MSG_MAP(GetMinGfxclkFrequency,          PPSMC_MSG_GetMinGfxclkFrequency,        1),
0094     MSG_MAP(GetMaxGfxclkFrequency,          PPSMC_MSG_GetMaxGfxclkFrequency,        1),
0095     MSG_MAP(SoftReset,                      PPSMC_MSG_SoftReset,                    1),
0096     MSG_MAP(SetGfxCGPG,                     PPSMC_MSG_SetGfxCGPG,                   1),
0097     MSG_MAP(SetSoftMaxGfxClk,               PPSMC_MSG_SetSoftMaxGfxClk,             1),
0098     MSG_MAP(SetHardMinGfxClk,               PPSMC_MSG_SetHardMinGfxClk,             1),
0099     MSG_MAP(SetSoftMaxSocclkByFreq,         PPSMC_MSG_SetSoftMaxSocclkByFreq,       1),
0100     MSG_MAP(SetSoftMaxFclkByFreq,           PPSMC_MSG_SetSoftMaxFclkByFreq,         1),
0101     MSG_MAP(SetSoftMaxVcn,                  PPSMC_MSG_SetSoftMaxVcn,                1),
0102     MSG_MAP(PowerGateMmHub,                 PPSMC_MSG_PowerGateMmHub,               1),
0103     MSG_MAP(UpdatePmeRestore,               PPSMC_MSG_UpdatePmeRestore,             1),
0104     MSG_MAP(GpuChangeState,                 PPSMC_MSG_GpuChangeState,               1),
0105     MSG_MAP(SetPowerLimitPercentage,        PPSMC_MSG_SetPowerLimitPercentage,      1),
0106     MSG_MAP(ForceGfxContentSave,            PPSMC_MSG_ForceGfxContentSave,          1),
0107     MSG_MAP(EnableTmdp48MHzRefclkPwrDown,   PPSMC_MSG_EnableTmdp48MHzRefclkPwrDown, 1),
0108     MSG_MAP(PowerDownJpeg,                  PPSMC_MSG_PowerDownJpeg,                1),
0109     MSG_MAP(PowerUpJpeg,                    PPSMC_MSG_PowerUpJpeg,                  1),
0110     MSG_MAP(PowerGateAtHub,                 PPSMC_MSG_PowerGateAtHub,               1),
0111     MSG_MAP(SetSoftMinJpeg,                 PPSMC_MSG_SetSoftMinJpeg,               1),
0112     MSG_MAP(SetHardMinFclkByFreq,           PPSMC_MSG_SetHardMinFclkByFreq,         1),
0113 };
0114 
0115 static struct cmn2asic_mapping renoir_clk_map[SMU_CLK_COUNT] = {
0116     CLK_MAP(GFXCLK, CLOCK_GFXCLK),
0117     CLK_MAP(SCLK,   CLOCK_GFXCLK),
0118     CLK_MAP(SOCCLK, CLOCK_SOCCLK),
0119     CLK_MAP(UCLK, CLOCK_FCLK),
0120     CLK_MAP(MCLK, CLOCK_FCLK),
0121     CLK_MAP(VCLK, CLOCK_VCLK),
0122     CLK_MAP(DCLK, CLOCK_DCLK),
0123 };
0124 
0125 static struct cmn2asic_mapping renoir_table_map[SMU_TABLE_COUNT] = {
0126     TAB_MAP_VALID(WATERMARKS),
0127     TAB_MAP_INVALID(CUSTOM_DPM),
0128     TAB_MAP_VALID(DPMCLOCKS),
0129     TAB_MAP_VALID(SMU_METRICS),
0130 };
0131 
0132 static struct cmn2asic_mapping renoir_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
0133     WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D,     WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
0134     WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,        WORKLOAD_PPLIB_VIDEO_BIT),
0135     WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR,           WORKLOAD_PPLIB_VR_BIT),
0136     WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,      WORKLOAD_PPLIB_COMPUTE_BIT),
0137     WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,       WORKLOAD_PPLIB_CUSTOM_BIT),
0138 };
0139 
0140 static const uint8_t renoir_throttler_map[] = {
0141     [THROTTLER_STATUS_BIT_SPL]      = (SMU_THROTTLER_SPL_BIT),
0142     [THROTTLER_STATUS_BIT_FPPT]     = (SMU_THROTTLER_FPPT_BIT),
0143     [THROTTLER_STATUS_BIT_SPPT]     = (SMU_THROTTLER_SPPT_BIT),
0144     [THROTTLER_STATUS_BIT_SPPT_APU]     = (SMU_THROTTLER_SPPT_APU_BIT),
0145     [THROTTLER_STATUS_BIT_THM_CORE]     = (SMU_THROTTLER_TEMP_CORE_BIT),
0146     [THROTTLER_STATUS_BIT_THM_GFX]      = (SMU_THROTTLER_TEMP_GPU_BIT),
0147     [THROTTLER_STATUS_BIT_THM_SOC]      = (SMU_THROTTLER_TEMP_SOC_BIT),
0148     [THROTTLER_STATUS_BIT_TDC_VDD]      = (SMU_THROTTLER_TDC_VDD_BIT),
0149     [THROTTLER_STATUS_BIT_TDC_SOC]      = (SMU_THROTTLER_TDC_SOC_BIT),
0150     [THROTTLER_STATUS_BIT_PROCHOT_CPU]  = (SMU_THROTTLER_PROCHOT_CPU_BIT),
0151     [THROTTLER_STATUS_BIT_PROCHOT_GFX]  = (SMU_THROTTLER_PROCHOT_GFX_BIT),
0152     [THROTTLER_STATUS_BIT_EDC_CPU]      = (SMU_THROTTLER_EDC_CPU_BIT),
0153     [THROTTLER_STATUS_BIT_EDC_GFX]      = (SMU_THROTTLER_EDC_GFX_BIT),
0154 };
0155 
0156 static int renoir_init_smc_tables(struct smu_context *smu)
0157 {
0158     struct smu_table_context *smu_table = &smu->smu_table;
0159     struct smu_table *tables = smu_table->tables;
0160 
0161     SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
0162         PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
0163     SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),
0164         PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
0165     SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
0166         PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
0167 
0168     smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL);
0169     if (!smu_table->clocks_table)
0170         goto err0_out;
0171 
0172     smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
0173     if (!smu_table->metrics_table)
0174         goto err1_out;
0175     smu_table->metrics_time = 0;
0176 
0177     smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
0178     if (!smu_table->watermarks_table)
0179         goto err2_out;
0180 
0181     smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
0182     smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
0183     if (!smu_table->gpu_metrics_table)
0184         goto err3_out;
0185 
0186     return 0;
0187 
0188 err3_out:
0189     kfree(smu_table->watermarks_table);
0190 err2_out:
0191     kfree(smu_table->metrics_table);
0192 err1_out:
0193     kfree(smu_table->clocks_table);
0194 err0_out:
0195     return -ENOMEM;
0196 }
0197 
0198 /*
0199  * This interface just for getting uclk ultimate freq and should't introduce
0200  * other likewise function result in overmuch callback.
0201  */
0202 static int renoir_get_dpm_clk_limited(struct smu_context *smu, enum smu_clk_type clk_type,
0203                         uint32_t dpm_level, uint32_t *freq)
0204 {
0205     DpmClocks_t *clk_table = smu->smu_table.clocks_table;
0206 
0207     if (!clk_table || clk_type >= SMU_CLK_COUNT)
0208         return -EINVAL;
0209 
0210     switch (clk_type) {
0211     case SMU_SOCCLK:
0212         if (dpm_level >= NUM_SOCCLK_DPM_LEVELS)
0213             return -EINVAL;
0214         *freq = clk_table->SocClocks[dpm_level].Freq;
0215         break;
0216     case SMU_UCLK:
0217     case SMU_MCLK:
0218         if (dpm_level >= NUM_FCLK_DPM_LEVELS)
0219             return -EINVAL;
0220         *freq = clk_table->FClocks[dpm_level].Freq;
0221         break;
0222     case SMU_DCEFCLK:
0223         if (dpm_level >= NUM_DCFCLK_DPM_LEVELS)
0224             return -EINVAL;
0225         *freq = clk_table->DcfClocks[dpm_level].Freq;
0226         break;
0227     case SMU_FCLK:
0228         if (dpm_level >= NUM_FCLK_DPM_LEVELS)
0229             return -EINVAL;
0230         *freq = clk_table->FClocks[dpm_level].Freq;
0231         break;
0232     case SMU_VCLK:
0233         if (dpm_level >= NUM_VCN_DPM_LEVELS)
0234             return -EINVAL;
0235         *freq = clk_table->VClocks[dpm_level].Freq;
0236         break;
0237     case SMU_DCLK:
0238         if (dpm_level >= NUM_VCN_DPM_LEVELS)
0239             return -EINVAL;
0240         *freq = clk_table->DClocks[dpm_level].Freq;
0241         break;
0242 
0243     default:
0244         return -EINVAL;
0245     }
0246 
0247     return 0;
0248 }
0249 
0250 static int renoir_get_profiling_clk_mask(struct smu_context *smu,
0251                      enum amd_dpm_forced_level level,
0252                      uint32_t *sclk_mask,
0253                      uint32_t *mclk_mask,
0254                      uint32_t *soc_mask)
0255 {
0256 
0257     if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
0258         if (sclk_mask)
0259             *sclk_mask = 0;
0260     } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
0261         if (mclk_mask)
0262             /* mclk levels are in reverse order */
0263             *mclk_mask = NUM_MEMCLK_DPM_LEVELS - 1;
0264     } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
0265         if(sclk_mask)
0266             /* The sclk as gfxclk and has three level about max/min/current */
0267             *sclk_mask = 3 - 1;
0268 
0269         if(mclk_mask)
0270             /* mclk levels are in reverse order */
0271             *mclk_mask = 0;
0272 
0273         if(soc_mask)
0274             *soc_mask = NUM_SOCCLK_DPM_LEVELS - 1;
0275     }
0276 
0277     return 0;
0278 }
0279 
0280 static int renoir_get_dpm_ultimate_freq(struct smu_context *smu,
0281                     enum smu_clk_type clk_type,
0282                     uint32_t *min,
0283                     uint32_t *max)
0284 {
0285     int ret = 0;
0286     uint32_t mclk_mask, soc_mask;
0287     uint32_t clock_limit;
0288 
0289     if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) {
0290         switch (clk_type) {
0291         case SMU_MCLK:
0292         case SMU_UCLK:
0293             clock_limit = smu->smu_table.boot_values.uclk;
0294             break;
0295         case SMU_GFXCLK:
0296         case SMU_SCLK:
0297             clock_limit = smu->smu_table.boot_values.gfxclk;
0298             break;
0299         case SMU_SOCCLK:
0300             clock_limit = smu->smu_table.boot_values.socclk;
0301             break;
0302         default:
0303             clock_limit = 0;
0304             break;
0305         }
0306 
0307         /* clock in Mhz unit */
0308         if (min)
0309             *min = clock_limit / 100;
0310         if (max)
0311             *max = clock_limit / 100;
0312 
0313         return 0;
0314     }
0315 
0316     if (max) {
0317         ret = renoir_get_profiling_clk_mask(smu,
0318                             AMD_DPM_FORCED_LEVEL_PROFILE_PEAK,
0319                             NULL,
0320                             &mclk_mask,
0321                             &soc_mask);
0322         if (ret)
0323             goto failed;
0324 
0325         switch (clk_type) {
0326         case SMU_GFXCLK:
0327         case SMU_SCLK:
0328             ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMaxGfxclkFrequency, max);
0329             if (ret) {
0330                 dev_err(smu->adev->dev, "Attempt to get max GX frequency from SMC Failed !\n");
0331                 goto failed;
0332             }
0333             break;
0334         case SMU_UCLK:
0335         case SMU_FCLK:
0336         case SMU_MCLK:
0337             ret = renoir_get_dpm_clk_limited(smu, clk_type, mclk_mask, max);
0338             if (ret)
0339                 goto failed;
0340             break;
0341         case SMU_SOCCLK:
0342             ret = renoir_get_dpm_clk_limited(smu, clk_type, soc_mask, max);
0343             if (ret)
0344                 goto failed;
0345             break;
0346         default:
0347             ret = -EINVAL;
0348             goto failed;
0349         }
0350     }
0351 
0352     if (min) {
0353         switch (clk_type) {
0354         case SMU_GFXCLK:
0355         case SMU_SCLK:
0356             ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMinGfxclkFrequency, min);
0357             if (ret) {
0358                 dev_err(smu->adev->dev, "Attempt to get min GX frequency from SMC Failed !\n");
0359                 goto failed;
0360             }
0361             break;
0362         case SMU_UCLK:
0363         case SMU_FCLK:
0364         case SMU_MCLK:
0365             ret = renoir_get_dpm_clk_limited(smu, clk_type, NUM_MEMCLK_DPM_LEVELS - 1, min);
0366             if (ret)
0367                 goto failed;
0368             break;
0369         case SMU_SOCCLK:
0370             ret = renoir_get_dpm_clk_limited(smu, clk_type, 0, min);
0371             if (ret)
0372                 goto failed;
0373             break;
0374         default:
0375             ret = -EINVAL;
0376             goto failed;
0377         }
0378     }
0379 failed:
0380     return ret;
0381 }
0382 
0383 static int renoir_od_edit_dpm_table(struct smu_context *smu,
0384                             enum PP_OD_DPM_TABLE_COMMAND type,
0385                             long input[], uint32_t size)
0386 {
0387     int ret = 0;
0388     struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
0389 
0390     if (!(smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL)) {
0391         dev_warn(smu->adev->dev,
0392             "pp_od_clk_voltage is not accessible if power_dpm_force_performance_level is not in manual mode!\n");
0393         return -EINVAL;
0394     }
0395 
0396     switch (type) {
0397     case PP_OD_EDIT_SCLK_VDDC_TABLE:
0398         if (size != 2) {
0399             dev_err(smu->adev->dev, "Input parameter number not correct\n");
0400             return -EINVAL;
0401         }
0402 
0403         if (input[0] == 0) {
0404             if (input[1] < smu->gfx_default_hard_min_freq) {
0405                 dev_warn(smu->adev->dev,
0406                     "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
0407                     input[1], smu->gfx_default_hard_min_freq);
0408                 return -EINVAL;
0409             }
0410             smu->gfx_actual_hard_min_freq = input[1];
0411         } else if (input[0] == 1) {
0412             if (input[1] > smu->gfx_default_soft_max_freq) {
0413                 dev_warn(smu->adev->dev,
0414                     "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
0415                     input[1], smu->gfx_default_soft_max_freq);
0416                 return -EINVAL;
0417             }
0418             smu->gfx_actual_soft_max_freq = input[1];
0419         } else {
0420             return -EINVAL;
0421         }
0422         break;
0423     case PP_OD_RESTORE_DEFAULT_TABLE:
0424         if (size != 0) {
0425             dev_err(smu->adev->dev, "Input parameter number not correct\n");
0426             return -EINVAL;
0427         }
0428         smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
0429         smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
0430         break;
0431     case PP_OD_COMMIT_DPM_TABLE:
0432         if (size != 0) {
0433             dev_err(smu->adev->dev, "Input parameter number not correct\n");
0434             return -EINVAL;
0435         } else {
0436             if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) {
0437                 dev_err(smu->adev->dev,
0438                     "The setting minimum sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
0439                     smu->gfx_actual_hard_min_freq,
0440                     smu->gfx_actual_soft_max_freq);
0441                 return -EINVAL;
0442             }
0443 
0444             ret = smu_cmn_send_smc_msg_with_param(smu,
0445                                 SMU_MSG_SetHardMinGfxClk,
0446                                 smu->gfx_actual_hard_min_freq,
0447                                 NULL);
0448             if (ret) {
0449                 dev_err(smu->adev->dev, "Set hard min sclk failed!");
0450                 return ret;
0451             }
0452 
0453             ret = smu_cmn_send_smc_msg_with_param(smu,
0454                                 SMU_MSG_SetSoftMaxGfxClk,
0455                                 smu->gfx_actual_soft_max_freq,
0456                                 NULL);
0457             if (ret) {
0458                 dev_err(smu->adev->dev, "Set soft max sclk failed!");
0459                 return ret;
0460             }
0461         }
0462         break;
0463     default:
0464         return -ENOSYS;
0465     }
0466 
0467     return ret;
0468 }
0469 
0470 static int renoir_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
0471 {
0472     uint32_t min = 0, max = 0;
0473     uint32_t ret = 0;
0474 
0475     ret = smu_cmn_send_smc_msg_with_param(smu,
0476                                 SMU_MSG_GetMinGfxclkFrequency,
0477                                 0, &min);
0478     if (ret)
0479         return ret;
0480     ret = smu_cmn_send_smc_msg_with_param(smu,
0481                                 SMU_MSG_GetMaxGfxclkFrequency,
0482                                 0, &max);
0483     if (ret)
0484         return ret;
0485 
0486     smu->gfx_default_hard_min_freq = min;
0487     smu->gfx_default_soft_max_freq = max;
0488     smu->gfx_actual_hard_min_freq = 0;
0489     smu->gfx_actual_soft_max_freq = 0;
0490 
0491     return 0;
0492 }
0493 
0494 static int renoir_print_clk_levels(struct smu_context *smu,
0495             enum smu_clk_type clk_type, char *buf)
0496 {
0497     int i, size = 0, ret = 0;
0498     uint32_t cur_value = 0, value = 0, count = 0, min = 0, max = 0;
0499     SmuMetrics_t metrics;
0500     struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
0501     bool cur_value_match_level = false;
0502 
0503     memset(&metrics, 0, sizeof(metrics));
0504 
0505     ret = smu_cmn_get_metrics_table(smu, &metrics, false);
0506     if (ret)
0507         return ret;
0508 
0509     smu_cmn_get_sysfs_buf(&buf, &size);
0510 
0511     switch (clk_type) {
0512     case SMU_OD_RANGE:
0513         if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
0514             ret = smu_cmn_send_smc_msg_with_param(smu,
0515                         SMU_MSG_GetMinGfxclkFrequency,
0516                         0, &min);
0517             if (ret)
0518                 return ret;
0519             ret = smu_cmn_send_smc_msg_with_param(smu,
0520                         SMU_MSG_GetMaxGfxclkFrequency,
0521                         0, &max);
0522             if (ret)
0523                 return ret;
0524             size += sysfs_emit_at(buf, size, "OD_RANGE\nSCLK: %10uMhz %10uMhz\n", min, max);
0525         }
0526         break;
0527     case SMU_OD_SCLK:
0528         if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
0529             min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
0530             max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
0531             size += sysfs_emit_at(buf, size, "OD_SCLK\n");
0532             size += sysfs_emit_at(buf, size, "0:%10uMhz\n", min);
0533             size += sysfs_emit_at(buf, size, "1:%10uMhz\n", max);
0534         }
0535         break;
0536     case SMU_GFXCLK:
0537     case SMU_SCLK:
0538         /* retirve table returned paramters unit is MHz */
0539         cur_value = metrics.ClockFrequency[CLOCK_GFXCLK];
0540         ret = renoir_get_dpm_ultimate_freq(smu, SMU_GFXCLK, &min, &max);
0541         if (!ret) {
0542             /* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
0543             if (cur_value  == max)
0544                 i = 2;
0545             else if (cur_value == min)
0546                 i = 0;
0547             else
0548                 i = 1;
0549 
0550             size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
0551                     i == 0 ? "*" : "");
0552             size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
0553                     i == 1 ? cur_value : RENOIR_UMD_PSTATE_GFXCLK,
0554                     i == 1 ? "*" : "");
0555             size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
0556                     i == 2 ? "*" : "");
0557         }
0558         return size;
0559     case SMU_SOCCLK:
0560         count = NUM_SOCCLK_DPM_LEVELS;
0561         cur_value = metrics.ClockFrequency[CLOCK_SOCCLK];
0562         break;
0563     case SMU_MCLK:
0564         count = NUM_MEMCLK_DPM_LEVELS;
0565         cur_value = metrics.ClockFrequency[CLOCK_FCLK];
0566         break;
0567     case SMU_DCEFCLK:
0568         count = NUM_DCFCLK_DPM_LEVELS;
0569         cur_value = metrics.ClockFrequency[CLOCK_DCFCLK];
0570         break;
0571     case SMU_FCLK:
0572         count = NUM_FCLK_DPM_LEVELS;
0573         cur_value = metrics.ClockFrequency[CLOCK_FCLK];
0574         break;
0575     case SMU_VCLK:
0576         count = NUM_VCN_DPM_LEVELS;
0577         cur_value = metrics.ClockFrequency[CLOCK_VCLK];
0578         break;
0579     case SMU_DCLK:
0580         count = NUM_VCN_DPM_LEVELS;
0581         cur_value = metrics.ClockFrequency[CLOCK_DCLK];
0582         break;
0583     default:
0584         break;
0585     }
0586 
0587     switch (clk_type) {
0588     case SMU_GFXCLK:
0589     case SMU_SCLK:
0590     case SMU_SOCCLK:
0591     case SMU_MCLK:
0592     case SMU_DCEFCLK:
0593     case SMU_FCLK:
0594     case SMU_VCLK:
0595     case SMU_DCLK:
0596         for (i = 0; i < count; i++) {
0597             ret = renoir_get_dpm_clk_limited(smu, clk_type, i, &value);
0598             if (ret)
0599                 return ret;
0600             if (!value)
0601                 continue;
0602             size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value,
0603                     cur_value == value ? "*" : "");
0604             if (cur_value == value)
0605                 cur_value_match_level = true;
0606         }
0607 
0608         if (!cur_value_match_level)
0609             size += sysfs_emit_at(buf, size, "   %uMhz *\n", cur_value);
0610 
0611         break;
0612     default:
0613         break;
0614     }
0615 
0616     return size;
0617 }
0618 
0619 static enum amd_pm_state_type renoir_get_current_power_state(struct smu_context *smu)
0620 {
0621     enum amd_pm_state_type pm_type;
0622     struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
0623 
0624     if (!smu_dpm_ctx->dpm_context ||
0625         !smu_dpm_ctx->dpm_current_power_state)
0626         return -EINVAL;
0627 
0628     switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
0629     case SMU_STATE_UI_LABEL_BATTERY:
0630         pm_type = POWER_STATE_TYPE_BATTERY;
0631         break;
0632     case SMU_STATE_UI_LABEL_BALLANCED:
0633         pm_type = POWER_STATE_TYPE_BALANCED;
0634         break;
0635     case SMU_STATE_UI_LABEL_PERFORMANCE:
0636         pm_type = POWER_STATE_TYPE_PERFORMANCE;
0637         break;
0638     default:
0639         if (smu_dpm_ctx->dpm_current_power_state->classification.flags & SMU_STATE_CLASSIFICATION_FLAG_BOOT)
0640             pm_type = POWER_STATE_TYPE_INTERNAL_BOOT;
0641         else
0642             pm_type = POWER_STATE_TYPE_DEFAULT;
0643         break;
0644     }
0645 
0646     return pm_type;
0647 }
0648 
0649 static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
0650 {
0651     int ret = 0;
0652 
0653     if (enable) {
0654         /* vcn dpm on is a prerequisite for vcn power gate messages */
0655         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
0656             ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL);
0657             if (ret)
0658                 return ret;
0659         }
0660     } else {
0661         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
0662             ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
0663             if (ret)
0664                 return ret;
0665         }
0666     }
0667 
0668     return ret;
0669 }
0670 
0671 static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
0672 {
0673     int ret = 0;
0674 
0675     if (enable) {
0676         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
0677             ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpJpeg, 0, NULL);
0678             if (ret)
0679                 return ret;
0680         }
0681     } else {
0682         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
0683             ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL);
0684             if (ret)
0685                 return ret;
0686         }
0687     }
0688 
0689     return ret;
0690 }
0691 
0692 static int renoir_force_dpm_limit_value(struct smu_context *smu, bool highest)
0693 {
0694     int ret = 0, i = 0;
0695     uint32_t min_freq, max_freq, force_freq;
0696     enum smu_clk_type clk_type;
0697 
0698     enum smu_clk_type clks[] = {
0699         SMU_GFXCLK,
0700         SMU_MCLK,
0701         SMU_SOCCLK,
0702     };
0703 
0704     for (i = 0; i < ARRAY_SIZE(clks); i++) {
0705         clk_type = clks[i];
0706         ret = renoir_get_dpm_ultimate_freq(smu, clk_type, &min_freq, &max_freq);
0707         if (ret)
0708             return ret;
0709 
0710         force_freq = highest ? max_freq : min_freq;
0711         ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq);
0712         if (ret)
0713             return ret;
0714     }
0715 
0716     return ret;
0717 }
0718 
0719 static int renoir_unforce_dpm_levels(struct smu_context *smu) {
0720 
0721     int ret = 0, i = 0;
0722     uint32_t min_freq, max_freq;
0723     enum smu_clk_type clk_type;
0724 
0725     struct clk_feature_map {
0726         enum smu_clk_type clk_type;
0727         uint32_t    feature;
0728     } clk_feature_map[] = {
0729         {SMU_GFXCLK, SMU_FEATURE_DPM_GFXCLK_BIT},
0730         {SMU_MCLK,   SMU_FEATURE_DPM_UCLK_BIT},
0731         {SMU_SOCCLK, SMU_FEATURE_DPM_SOCCLK_BIT},
0732     };
0733 
0734     for (i = 0; i < ARRAY_SIZE(clk_feature_map); i++) {
0735         if (!smu_cmn_feature_is_enabled(smu, clk_feature_map[i].feature))
0736             continue;
0737 
0738         clk_type = clk_feature_map[i].clk_type;
0739 
0740         ret = renoir_get_dpm_ultimate_freq(smu, clk_type, &min_freq, &max_freq);
0741         if (ret)
0742             return ret;
0743 
0744         ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
0745         if (ret)
0746             return ret;
0747     }
0748 
0749     return ret;
0750 }
0751 
0752 /*
0753  * This interface get dpm clock table for dc
0754  */
0755 static int renoir_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks *clock_table)
0756 {
0757     DpmClocks_t *table = smu->smu_table.clocks_table;
0758     int i;
0759 
0760     if (!clock_table || !table)
0761         return -EINVAL;
0762 
0763     for (i = 0; i < NUM_DCFCLK_DPM_LEVELS; i++) {
0764         clock_table->DcfClocks[i].Freq = table->DcfClocks[i].Freq;
0765         clock_table->DcfClocks[i].Vol = table->DcfClocks[i].Vol;
0766     }
0767 
0768     for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) {
0769         clock_table->SocClocks[i].Freq = table->SocClocks[i].Freq;
0770         clock_table->SocClocks[i].Vol = table->SocClocks[i].Vol;
0771     }
0772 
0773     for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) {
0774         clock_table->FClocks[i].Freq = table->FClocks[i].Freq;
0775         clock_table->FClocks[i].Vol = table->FClocks[i].Vol;
0776     }
0777 
0778     for (i = 0; i<  NUM_MEMCLK_DPM_LEVELS; i++) {
0779         clock_table->MemClocks[i].Freq = table->MemClocks[i].Freq;
0780         clock_table->MemClocks[i].Vol = table->MemClocks[i].Vol;
0781     }
0782 
0783     for (i = 0; i < NUM_VCN_DPM_LEVELS; i++) {
0784         clock_table->VClocks[i].Freq = table->VClocks[i].Freq;
0785         clock_table->VClocks[i].Vol = table->VClocks[i].Vol;
0786     }
0787 
0788     for (i = 0; i < NUM_VCN_DPM_LEVELS; i++) {
0789         clock_table->DClocks[i].Freq = table->DClocks[i].Freq;
0790         clock_table->DClocks[i].Vol = table->DClocks[i].Vol;
0791     }
0792 
0793     return 0;
0794 }
0795 
0796 static int renoir_force_clk_levels(struct smu_context *smu,
0797                    enum smu_clk_type clk_type, uint32_t mask)
0798 {
0799 
0800     int ret = 0 ;
0801     uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0;
0802 
0803     soft_min_level = mask ? (ffs(mask) - 1) : 0;
0804     soft_max_level = mask ? (fls(mask) - 1) : 0;
0805 
0806     switch (clk_type) {
0807     case SMU_GFXCLK:
0808     case SMU_SCLK:
0809         if (soft_min_level > 2 || soft_max_level > 2) {
0810             dev_info(smu->adev->dev, "Currently sclk only support 3 levels on APU\n");
0811             return -EINVAL;
0812         }
0813 
0814         ret = renoir_get_dpm_ultimate_freq(smu, SMU_GFXCLK, &min_freq, &max_freq);
0815         if (ret)
0816             return ret;
0817         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
0818                     soft_max_level == 0 ? min_freq :
0819                     soft_max_level == 1 ? RENOIR_UMD_PSTATE_GFXCLK : max_freq,
0820                     NULL);
0821         if (ret)
0822             return ret;
0823         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
0824                     soft_min_level == 2 ? max_freq :
0825                     soft_min_level == 1 ? RENOIR_UMD_PSTATE_GFXCLK : min_freq,
0826                     NULL);
0827         if (ret)
0828             return ret;
0829         break;
0830     case SMU_SOCCLK:
0831         ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_min_level, &min_freq);
0832         if (ret)
0833             return ret;
0834         ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_max_level, &max_freq);
0835         if (ret)
0836             return ret;
0837         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxSocclkByFreq, max_freq, NULL);
0838         if (ret)
0839             return ret;
0840         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinSocclkByFreq, min_freq, NULL);
0841         if (ret)
0842             return ret;
0843         break;
0844     case SMU_MCLK:
0845     case SMU_FCLK:
0846         ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_min_level, &min_freq);
0847         if (ret)
0848             return ret;
0849         ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_max_level, &max_freq);
0850         if (ret)
0851             return ret;
0852         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxFclkByFreq, max_freq, NULL);
0853         if (ret)
0854             return ret;
0855         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinFclkByFreq, min_freq, NULL);
0856         if (ret)
0857             return ret;
0858         break;
0859     default:
0860         break;
0861     }
0862 
0863     return ret;
0864 }
0865 
0866 static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
0867 {
0868     int workload_type, ret;
0869     uint32_t profile_mode = input[size];
0870 
0871     if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
0872         dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);
0873         return -EINVAL;
0874     }
0875 
0876     if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT ||
0877             profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)
0878         return 0;
0879 
0880     /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
0881     workload_type = smu_cmn_to_asic_specific_index(smu,
0882                                CMN2ASIC_MAPPING_WORKLOAD,
0883                                profile_mode);
0884     if (workload_type < 0) {
0885         /*
0886          * TODO: If some case need switch to powersave/default power mode
0887          * then can consider enter WORKLOAD_COMPUTE/WORKLOAD_CUSTOM for power saving.
0888          */
0889         dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on RENOIR\n", profile_mode);
0890         return -EINVAL;
0891     }
0892 
0893     ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
0894                     1 << workload_type,
0895                     NULL);
0896     if (ret) {
0897         dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", workload_type);
0898         return ret;
0899     }
0900 
0901     smu->power_profile_mode = profile_mode;
0902 
0903     return 0;
0904 }
0905 
0906 static int renoir_set_peak_clock_by_device(struct smu_context *smu)
0907 {
0908     int ret = 0;
0909     uint32_t sclk_freq = 0, uclk_freq = 0;
0910 
0911     ret = renoir_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_freq);
0912     if (ret)
0913         return ret;
0914 
0915     ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk_freq, sclk_freq);
0916     if (ret)
0917         return ret;
0918 
0919     ret = renoir_get_dpm_ultimate_freq(smu, SMU_UCLK, NULL, &uclk_freq);
0920     if (ret)
0921         return ret;
0922 
0923     ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_UCLK, uclk_freq, uclk_freq);
0924     if (ret)
0925         return ret;
0926 
0927     return ret;
0928 }
0929 
0930 static int renoir_set_performance_level(struct smu_context *smu,
0931                     enum amd_dpm_forced_level level)
0932 {
0933     int ret = 0;
0934     uint32_t sclk_mask, mclk_mask, soc_mask;
0935 
0936     switch (level) {
0937     case AMD_DPM_FORCED_LEVEL_HIGH:
0938         smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
0939         smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
0940 
0941         ret = renoir_force_dpm_limit_value(smu, true);
0942         break;
0943     case AMD_DPM_FORCED_LEVEL_LOW:
0944         smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
0945         smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
0946 
0947         ret = renoir_force_dpm_limit_value(smu, false);
0948         break;
0949     case AMD_DPM_FORCED_LEVEL_AUTO:
0950         smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
0951         smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
0952 
0953         ret = renoir_unforce_dpm_levels(smu);
0954         break;
0955     case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
0956         smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
0957         smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
0958 
0959         ret = smu_cmn_send_smc_msg_with_param(smu,
0960                               SMU_MSG_SetHardMinGfxClk,
0961                               RENOIR_UMD_PSTATE_GFXCLK,
0962                               NULL);
0963         if (ret)
0964             return ret;
0965         ret = smu_cmn_send_smc_msg_with_param(smu,
0966                               SMU_MSG_SetHardMinFclkByFreq,
0967                               RENOIR_UMD_PSTATE_FCLK,
0968                               NULL);
0969         if (ret)
0970             return ret;
0971         ret = smu_cmn_send_smc_msg_with_param(smu,
0972                               SMU_MSG_SetHardMinSocclkByFreq,
0973                               RENOIR_UMD_PSTATE_SOCCLK,
0974                               NULL);
0975         if (ret)
0976             return ret;
0977         ret = smu_cmn_send_smc_msg_with_param(smu,
0978                               SMU_MSG_SetHardMinVcn,
0979                               RENOIR_UMD_PSTATE_VCNCLK,
0980                               NULL);
0981         if (ret)
0982             return ret;
0983 
0984         ret = smu_cmn_send_smc_msg_with_param(smu,
0985                               SMU_MSG_SetSoftMaxGfxClk,
0986                               RENOIR_UMD_PSTATE_GFXCLK,
0987                               NULL);
0988         if (ret)
0989             return ret;
0990         ret = smu_cmn_send_smc_msg_with_param(smu,
0991                               SMU_MSG_SetSoftMaxFclkByFreq,
0992                               RENOIR_UMD_PSTATE_FCLK,
0993                               NULL);
0994         if (ret)
0995             return ret;
0996         ret = smu_cmn_send_smc_msg_with_param(smu,
0997                               SMU_MSG_SetSoftMaxSocclkByFreq,
0998                               RENOIR_UMD_PSTATE_SOCCLK,
0999                               NULL);
1000         if (ret)
1001             return ret;
1002         ret = smu_cmn_send_smc_msg_with_param(smu,
1003                               SMU_MSG_SetSoftMaxVcn,
1004                               RENOIR_UMD_PSTATE_VCNCLK,
1005                               NULL);
1006         if (ret)
1007             return ret;
1008         break;
1009     case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1010     case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1011         smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
1012         smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
1013 
1014         ret = renoir_get_profiling_clk_mask(smu, level,
1015                             &sclk_mask,
1016                             &mclk_mask,
1017                             &soc_mask);
1018         if (ret)
1019             return ret;
1020         renoir_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask);
1021         renoir_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask);
1022         renoir_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
1023         break;
1024     case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1025         smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
1026         smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
1027 
1028         ret = renoir_set_peak_clock_by_device(smu);
1029         break;
1030     case AMD_DPM_FORCED_LEVEL_MANUAL:
1031     case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
1032     default:
1033         break;
1034     }
1035     return ret;
1036 }
1037 
1038 /* save watermark settings into pplib smu structure,
1039  * also pass data to smu controller
1040  */
1041 static int renoir_set_watermarks_table(
1042         struct smu_context *smu,
1043         struct pp_smu_wm_range_sets *clock_ranges)
1044 {
1045     Watermarks_t *table = smu->smu_table.watermarks_table;
1046     int ret = 0;
1047     int i;
1048 
1049     if (clock_ranges) {
1050         if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES ||
1051             clock_ranges->num_writer_wm_sets > NUM_WM_RANGES)
1052             return -EINVAL;
1053 
1054         /* save into smu->smu_table.tables[SMU_TABLE_WATERMARKS]->cpu_addr*/
1055         for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
1056             table->WatermarkRow[WM_DCFCLK][i].MinClock =
1057                 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
1058             table->WatermarkRow[WM_DCFCLK][i].MaxClock =
1059                 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
1060             table->WatermarkRow[WM_DCFCLK][i].MinMclk =
1061                 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
1062             table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
1063                 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
1064 
1065             table->WatermarkRow[WM_DCFCLK][i].WmSetting =
1066                 clock_ranges->reader_wm_sets[i].wm_inst;
1067             table->WatermarkRow[WM_DCFCLK][i].WmType =
1068                 clock_ranges->reader_wm_sets[i].wm_type;
1069         }
1070 
1071         for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
1072             table->WatermarkRow[WM_SOCCLK][i].MinClock =
1073                 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
1074             table->WatermarkRow[WM_SOCCLK][i].MaxClock =
1075                 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
1076             table->WatermarkRow[WM_SOCCLK][i].MinMclk =
1077                 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
1078             table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
1079                 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
1080 
1081             table->WatermarkRow[WM_SOCCLK][i].WmSetting =
1082                 clock_ranges->writer_wm_sets[i].wm_inst;
1083             table->WatermarkRow[WM_SOCCLK][i].WmType =
1084                 clock_ranges->writer_wm_sets[i].wm_type;
1085         }
1086 
1087         smu->watermarks_bitmap |= WATERMARKS_EXIST;
1088     }
1089 
1090     /* pass data to smu controller */
1091     if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
1092          !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
1093         ret = smu_cmn_write_watermarks_table(smu);
1094         if (ret) {
1095             dev_err(smu->adev->dev, "Failed to update WMTABLE!");
1096             return ret;
1097         }
1098         smu->watermarks_bitmap |= WATERMARKS_LOADED;
1099     }
1100 
1101     return 0;
1102 }
1103 
1104 static int renoir_get_power_profile_mode(struct smu_context *smu,
1105                        char *buf)
1106 {
1107     uint32_t i, size = 0;
1108     int16_t workload_type = 0;
1109 
1110     if (!buf)
1111         return -EINVAL;
1112 
1113     for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
1114         /*
1115          * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1116          * Not all profile modes are supported on arcturus.
1117          */
1118         workload_type = smu_cmn_to_asic_specific_index(smu,
1119                                    CMN2ASIC_MAPPING_WORKLOAD,
1120                                    i);
1121         if (workload_type < 0)
1122             continue;
1123 
1124         size += sysfs_emit_at(buf, size, "%2d %14s%s\n",
1125             i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
1126     }
1127 
1128     return size;
1129 }
1130 
1131 static void renoir_get_ss_power_percent(SmuMetrics_t *metrics,
1132                     uint32_t *apu_percent, uint32_t *dgpu_percent)
1133 {
1134     uint32_t apu_boost = 0;
1135     uint32_t dgpu_boost = 0;
1136     uint16_t apu_limit = 0;
1137     uint16_t dgpu_limit = 0;
1138     uint16_t apu_power = 0;
1139     uint16_t dgpu_power = 0;
1140 
1141     apu_power = metrics->ApuPower;
1142     apu_limit = metrics->StapmOriginalLimit;
1143     if (apu_power > apu_limit && apu_limit != 0)
1144         apu_boost =  ((apu_power - apu_limit) * 100) / apu_limit;
1145     apu_boost = (apu_boost > 100) ? 100 : apu_boost;
1146 
1147     dgpu_power = metrics->dGpuPower;
1148     if (metrics->StapmCurrentLimit > metrics->StapmOriginalLimit)
1149         dgpu_limit = metrics->StapmCurrentLimit - metrics->StapmOriginalLimit;
1150     if (dgpu_power > dgpu_limit && dgpu_limit != 0)
1151         dgpu_boost = ((dgpu_power - dgpu_limit) * 100) / dgpu_limit;
1152     dgpu_boost = (dgpu_boost > 100) ? 100 : dgpu_boost;
1153 
1154     if (dgpu_boost >= apu_boost)
1155         apu_boost = 0;
1156     else
1157         dgpu_boost = 0;
1158 
1159     *apu_percent = apu_boost;
1160     *dgpu_percent = dgpu_boost;
1161 }
1162 
1163 
1164 static int renoir_get_smu_metrics_data(struct smu_context *smu,
1165                        MetricsMember_t member,
1166                        uint32_t *value)
1167 {
1168     struct smu_table_context *smu_table = &smu->smu_table;
1169 
1170     SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
1171     int ret = 0;
1172     uint32_t apu_percent = 0;
1173     uint32_t dgpu_percent = 0;
1174 
1175 
1176     ret = smu_cmn_get_metrics_table(smu,
1177                     NULL,
1178                     false);
1179     if (ret)
1180         return ret;
1181 
1182     switch (member) {
1183     case METRICS_AVERAGE_GFXCLK:
1184         *value = metrics->ClockFrequency[CLOCK_GFXCLK];
1185         break;
1186     case METRICS_AVERAGE_SOCCLK:
1187         *value = metrics->ClockFrequency[CLOCK_SOCCLK];
1188         break;
1189     case METRICS_AVERAGE_UCLK:
1190         *value = metrics->ClockFrequency[CLOCK_FCLK];
1191         break;
1192     case METRICS_AVERAGE_GFXACTIVITY:
1193         *value = metrics->AverageGfxActivity / 100;
1194         break;
1195     case METRICS_AVERAGE_VCNACTIVITY:
1196         *value = metrics->AverageUvdActivity / 100;
1197         break;
1198     case METRICS_AVERAGE_SOCKETPOWER:
1199         *value = (metrics->CurrentSocketPower << 8) / 1000;
1200         break;
1201     case METRICS_TEMPERATURE_EDGE:
1202         *value = (metrics->GfxTemperature / 100) *
1203             SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1204         break;
1205     case METRICS_TEMPERATURE_HOTSPOT:
1206         *value = (metrics->SocTemperature / 100) *
1207             SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1208         break;
1209     case METRICS_THROTTLER_STATUS:
1210         *value = metrics->ThrottlerStatus;
1211         break;
1212     case METRICS_VOLTAGE_VDDGFX:
1213         *value = metrics->Voltage[0];
1214         break;
1215     case METRICS_VOLTAGE_VDDSOC:
1216         *value = metrics->Voltage[1];
1217         break;
1218     case METRICS_SS_APU_SHARE:
1219         /* return the percentage of APU power boost
1220          * with respect to APU's power limit.
1221          */
1222         renoir_get_ss_power_percent(metrics, &apu_percent, &dgpu_percent);
1223         *value = apu_percent;
1224         break;
1225     case METRICS_SS_DGPU_SHARE:
1226         /* return the percentage of dGPU power boost
1227          * with respect to dGPU's power limit.
1228          */
1229         renoir_get_ss_power_percent(metrics, &apu_percent, &dgpu_percent);
1230         *value = dgpu_percent;
1231         break;
1232     default:
1233         *value = UINT_MAX;
1234         break;
1235     }
1236 
1237     return ret;
1238 }
1239 
1240 static int renoir_read_sensor(struct smu_context *smu,
1241                  enum amd_pp_sensors sensor,
1242                  void *data, uint32_t *size)
1243 {
1244     int ret = 0;
1245 
1246     if (!data || !size)
1247         return -EINVAL;
1248 
1249     switch (sensor) {
1250     case AMDGPU_PP_SENSOR_GPU_LOAD:
1251         ret = renoir_get_smu_metrics_data(smu,
1252                           METRICS_AVERAGE_GFXACTIVITY,
1253                           (uint32_t *)data);
1254         *size = 4;
1255         break;
1256     case AMDGPU_PP_SENSOR_EDGE_TEMP:
1257         ret = renoir_get_smu_metrics_data(smu,
1258                           METRICS_TEMPERATURE_EDGE,
1259                           (uint32_t *)data);
1260         *size = 4;
1261         break;
1262     case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1263         ret = renoir_get_smu_metrics_data(smu,
1264                           METRICS_TEMPERATURE_HOTSPOT,
1265                           (uint32_t *)data);
1266         *size = 4;
1267         break;
1268     case AMDGPU_PP_SENSOR_GFX_MCLK:
1269         ret = renoir_get_smu_metrics_data(smu,
1270                           METRICS_AVERAGE_UCLK,
1271                           (uint32_t *)data);
1272         *(uint32_t *)data *= 100;
1273         *size = 4;
1274         break;
1275     case AMDGPU_PP_SENSOR_GFX_SCLK:
1276         ret = renoir_get_smu_metrics_data(smu,
1277                           METRICS_AVERAGE_GFXCLK,
1278                           (uint32_t *)data);
1279         *(uint32_t *)data *= 100;
1280         *size = 4;
1281         break;
1282     case AMDGPU_PP_SENSOR_VDDGFX:
1283         ret = renoir_get_smu_metrics_data(smu,
1284                           METRICS_VOLTAGE_VDDGFX,
1285                           (uint32_t *)data);
1286         *size = 4;
1287         break;
1288     case AMDGPU_PP_SENSOR_VDDNB:
1289         ret = renoir_get_smu_metrics_data(smu,
1290                           METRICS_VOLTAGE_VDDSOC,
1291                           (uint32_t *)data);
1292         *size = 4;
1293         break;
1294     case AMDGPU_PP_SENSOR_GPU_POWER:
1295         ret = renoir_get_smu_metrics_data(smu,
1296                           METRICS_AVERAGE_SOCKETPOWER,
1297                           (uint32_t *)data);
1298         *size = 4;
1299         break;
1300     case AMDGPU_PP_SENSOR_SS_APU_SHARE:
1301         ret = renoir_get_smu_metrics_data(smu,
1302                           METRICS_SS_APU_SHARE,
1303                           (uint32_t *)data);
1304         *size = 4;
1305         break;
1306     case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
1307         ret = renoir_get_smu_metrics_data(smu,
1308                           METRICS_SS_DGPU_SHARE,
1309                           (uint32_t *)data);
1310         *size = 4;
1311         break;
1312     default:
1313         ret = -EOPNOTSUPP;
1314         break;
1315     }
1316 
1317     return ret;
1318 }
1319 
1320 static bool renoir_is_dpm_running(struct smu_context *smu)
1321 {
1322     struct amdgpu_device *adev = smu->adev;
1323 
1324     /*
1325      * Until now, the pmfw hasn't exported the interface of SMU
1326      * feature mask to APU SKU so just force on all the feature
1327      * at early initial stage.
1328      */
1329     if (adev->in_suspend)
1330         return false;
1331     else
1332         return true;
1333 
1334 }
1335 
1336 static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
1337                       void **table)
1338 {
1339     struct smu_table_context *smu_table = &smu->smu_table;
1340     struct gpu_metrics_v2_2 *gpu_metrics =
1341         (struct gpu_metrics_v2_2 *)smu_table->gpu_metrics_table;
1342     SmuMetrics_t metrics;
1343     int ret = 0;
1344 
1345     ret = smu_cmn_get_metrics_table(smu, &metrics, true);
1346     if (ret)
1347         return ret;
1348 
1349     smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 2);
1350 
1351     gpu_metrics->temperature_gfx = metrics.GfxTemperature;
1352     gpu_metrics->temperature_soc = metrics.SocTemperature;
1353     memcpy(&gpu_metrics->temperature_core[0],
1354         &metrics.CoreTemperature[0],
1355         sizeof(uint16_t) * 8);
1356     gpu_metrics->temperature_l3[0] = metrics.L3Temperature[0];
1357     gpu_metrics->temperature_l3[1] = metrics.L3Temperature[1];
1358 
1359     gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity;
1360     gpu_metrics->average_mm_activity = metrics.AverageUvdActivity;
1361 
1362     gpu_metrics->average_socket_power = metrics.CurrentSocketPower;
1363     gpu_metrics->average_cpu_power = metrics.Power[0];
1364     gpu_metrics->average_soc_power = metrics.Power[1];
1365     memcpy(&gpu_metrics->average_core_power[0],
1366         &metrics.CorePower[0],
1367         sizeof(uint16_t) * 8);
1368 
1369     gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency;
1370     gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency;
1371     gpu_metrics->average_fclk_frequency = metrics.AverageFclkFrequency;
1372     gpu_metrics->average_vclk_frequency = metrics.AverageVclkFrequency;
1373 
1374     gpu_metrics->current_gfxclk = metrics.ClockFrequency[CLOCK_GFXCLK];
1375     gpu_metrics->current_socclk = metrics.ClockFrequency[CLOCK_SOCCLK];
1376     gpu_metrics->current_uclk = metrics.ClockFrequency[CLOCK_UMCCLK];
1377     gpu_metrics->current_fclk = metrics.ClockFrequency[CLOCK_FCLK];
1378     gpu_metrics->current_vclk = metrics.ClockFrequency[CLOCK_VCLK];
1379     gpu_metrics->current_dclk = metrics.ClockFrequency[CLOCK_DCLK];
1380     memcpy(&gpu_metrics->current_coreclk[0],
1381         &metrics.CoreFrequency[0],
1382         sizeof(uint16_t) * 8);
1383     gpu_metrics->current_l3clk[0] = metrics.L3Frequency[0];
1384     gpu_metrics->current_l3clk[1] = metrics.L3Frequency[1];
1385 
1386     gpu_metrics->throttle_status = metrics.ThrottlerStatus;
1387     gpu_metrics->indep_throttle_status =
1388         smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
1389                            renoir_throttler_map);
1390 
1391     gpu_metrics->fan_pwm = metrics.FanPwm;
1392 
1393     gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
1394 
1395     *table = (void *)gpu_metrics;
1396 
1397     return sizeof(struct gpu_metrics_v2_2);
1398 }
1399 
1400 static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state)
1401 {
1402 
1403     return 0;
1404 }
1405 
1406 static int renoir_get_enabled_mask(struct smu_context *smu,
1407                    uint64_t *feature_mask)
1408 {
1409     if (!feature_mask)
1410         return -EINVAL;
1411     memset(feature_mask, 0xff, sizeof(*feature_mask));
1412 
1413     return 0;
1414 }
1415 
1416 static const struct pptable_funcs renoir_ppt_funcs = {
1417     .set_power_state = NULL,
1418     .print_clk_levels = renoir_print_clk_levels,
1419     .get_current_power_state = renoir_get_current_power_state,
1420     .dpm_set_vcn_enable = renoir_dpm_set_vcn_enable,
1421     .dpm_set_jpeg_enable = renoir_dpm_set_jpeg_enable,
1422     .force_clk_levels = renoir_force_clk_levels,
1423     .set_power_profile_mode = renoir_set_power_profile_mode,
1424     .set_performance_level = renoir_set_performance_level,
1425     .get_dpm_clock_table = renoir_get_dpm_clock_table,
1426     .set_watermarks_table = renoir_set_watermarks_table,
1427     .get_power_profile_mode = renoir_get_power_profile_mode,
1428     .read_sensor = renoir_read_sensor,
1429     .check_fw_status = smu_v12_0_check_fw_status,
1430     .check_fw_version = smu_v12_0_check_fw_version,
1431     .powergate_sdma = smu_v12_0_powergate_sdma,
1432     .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
1433     .send_smc_msg = smu_cmn_send_smc_msg,
1434     .set_gfx_cgpg = smu_v12_0_set_gfx_cgpg,
1435     .gfx_off_control = smu_v12_0_gfx_off_control,
1436     .get_gfx_off_status = smu_v12_0_get_gfxoff_status,
1437     .init_smc_tables = renoir_init_smc_tables,
1438     .fini_smc_tables = smu_v12_0_fini_smc_tables,
1439     .set_default_dpm_table = smu_v12_0_set_default_dpm_tables,
1440     .get_enabled_mask = renoir_get_enabled_mask,
1441     .feature_is_enabled = smu_cmn_feature_is_enabled,
1442     .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception,
1443     .get_dpm_ultimate_freq = renoir_get_dpm_ultimate_freq,
1444     .mode2_reset = smu_v12_0_mode2_reset,
1445     .set_soft_freq_limited_range = smu_v12_0_set_soft_freq_limited_range,
1446     .set_driver_table_location = smu_v12_0_set_driver_table_location,
1447     .is_dpm_running = renoir_is_dpm_running,
1448     .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
1449     .set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
1450     .get_gpu_metrics = renoir_get_gpu_metrics,
1451     .gfx_state_change_set = renoir_gfx_state_change_set,
1452     .set_fine_grain_gfx_freq_parameters = renoir_set_fine_grain_gfx_freq_parameters,
1453     .od_edit_dpm_table = renoir_od_edit_dpm_table,
1454     .get_vbios_bootup_values = smu_v12_0_get_vbios_bootup_values,
1455 };
1456 
1457 void renoir_set_ppt_funcs(struct smu_context *smu)
1458 {
1459     struct amdgpu_device *adev = smu->adev;
1460 
1461     smu->ppt_funcs = &renoir_ppt_funcs;
1462     smu->message_map = renoir_message_map;
1463     smu->clock_map = renoir_clk_map;
1464     smu->table_map = renoir_table_map;
1465     smu->workload_map = renoir_workload_map;
1466     smu->smc_driver_if_version = SMU12_DRIVER_IF_VERSION;
1467     smu->is_apu = true;
1468     smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82);
1469     smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66);
1470     smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
1471 }