LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/pm/swsmu/smu12 - renoir_ppt.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 562 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 26 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2019 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  */
      23             : 
      24             : #define SWSMU_CODE_LAYER_L2
      25             : 
      26             : #include "amdgpu.h"
      27             : #include "amdgpu_smu.h"
      28             : #include "smu_v12_0_ppsmc.h"
      29             : #include "smu12_driver_if.h"
      30             : #include "smu_v12_0.h"
      31             : #include "renoir_ppt.h"
      32             : #include "smu_cmn.h"
      33             : 
      34             : /*
      35             :  * DO NOT use these for err/warn/info/debug messages.
      36             :  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
      37             :  * They are more MGPU friendly.
      38             :  */
      39             : #undef pr_err
      40             : #undef pr_warn
      41             : #undef pr_info
      42             : #undef pr_debug
      43             : 
      44             : #define mmMP1_SMN_C2PMSG_66                                                                            0x0282
      45             : #define mmMP1_SMN_C2PMSG_66_BASE_IDX                                                                   0
      46             : 
      47             : #define mmMP1_SMN_C2PMSG_82                                                                            0x0292
      48             : #define mmMP1_SMN_C2PMSG_82_BASE_IDX                                                                   0
      49             : 
      50             : #define mmMP1_SMN_C2PMSG_90                                                                            0x029a
      51             : #define mmMP1_SMN_C2PMSG_90_BASE_IDX                                                                   0
      52             : 
      53             : static struct cmn2asic_msg_mapping renoir_message_map[SMU_MSG_MAX_COUNT] = {
      54             :         MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage,                  1),
      55             :         MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetSmuVersion,                1),
      56             :         MSG_MAP(GetDriverIfVersion,             PPSMC_MSG_GetDriverIfVersion,           1),
      57             :         MSG_MAP(PowerUpGfx,                     PPSMC_MSG_PowerUpGfx,                   1),
      58             :         MSG_MAP(AllowGfxOff,                    PPSMC_MSG_EnableGfxOff,                 1),
      59             :         MSG_MAP(DisallowGfxOff,                 PPSMC_MSG_DisableGfxOff,                1),
      60             :         MSG_MAP(PowerDownIspByTile,             PPSMC_MSG_PowerDownIspByTile,           1),
      61             :         MSG_MAP(PowerUpIspByTile,               PPSMC_MSG_PowerUpIspByTile,             1),
      62             :         MSG_MAP(PowerDownVcn,                   PPSMC_MSG_PowerDownVcn,                 1),
      63             :         MSG_MAP(PowerUpVcn,                     PPSMC_MSG_PowerUpVcn,                   1),
      64             :         MSG_MAP(PowerDownSdma,                  PPSMC_MSG_PowerDownSdma,                1),
      65             :         MSG_MAP(PowerUpSdma,                    PPSMC_MSG_PowerUpSdma,                  1),
      66             :         MSG_MAP(SetHardMinIspclkByFreq,         PPSMC_MSG_SetHardMinIspclkByFreq,       1),
      67             :         MSG_MAP(SetHardMinVcn,                  PPSMC_MSG_SetHardMinVcn,                1),
      68             :         MSG_MAP(SetAllowFclkSwitch,             PPSMC_MSG_SetAllowFclkSwitch,           1),
      69             :         MSG_MAP(SetMinVideoGfxclkFreq,          PPSMC_MSG_SetMinVideoGfxclkFreq,        1),
      70             :         MSG_MAP(ActiveProcessNotify,            PPSMC_MSG_ActiveProcessNotify,          1),
      71             :         MSG_MAP(SetCustomPolicy,                PPSMC_MSG_SetCustomPolicy,              1),
      72             :         MSG_MAP(SetVideoFps,                    PPSMC_MSG_SetVideoFps,                  1),
      73             :         MSG_MAP(NumOfDisplays,                  PPSMC_MSG_SetDisplayCount,              1),
      74             :         MSG_MAP(QueryPowerLimit,                PPSMC_MSG_QueryPowerLimit,              1),
      75             :         MSG_MAP(SetDriverDramAddrHigh,          PPSMC_MSG_SetDriverDramAddrHigh,        1),
      76             :         MSG_MAP(SetDriverDramAddrLow,           PPSMC_MSG_SetDriverDramAddrLow,         1),
      77             :         MSG_MAP(TransferTableSmu2Dram,          PPSMC_MSG_TransferTableSmu2Dram,        1),
      78             :         MSG_MAP(TransferTableDram2Smu,          PPSMC_MSG_TransferTableDram2Smu,        1),
      79             :         MSG_MAP(GfxDeviceDriverReset,           PPSMC_MSG_GfxDeviceDriverReset,         1),
      80             :         MSG_MAP(SetGfxclkOverdriveByFreqVid,    PPSMC_MSG_SetGfxclkOverdriveByFreqVid,  1),
      81             :         MSG_MAP(SetHardMinDcfclkByFreq,         PPSMC_MSG_SetHardMinDcfclkByFreq,       1),
      82             :         MSG_MAP(SetHardMinSocclkByFreq,         PPSMC_MSG_SetHardMinSocclkByFreq,       1),
      83             :         MSG_MAP(ControlIgpuATS,                 PPSMC_MSG_ControlIgpuATS,               1),
      84             :         MSG_MAP(SetMinVideoFclkFreq,            PPSMC_MSG_SetMinVideoFclkFreq,          1),
      85             :         MSG_MAP(SetMinDeepSleepDcfclk,          PPSMC_MSG_SetMinDeepSleepDcfclk,        1),
      86             :         MSG_MAP(ForcePowerDownGfx,              PPSMC_MSG_ForcePowerDownGfx,            1),
      87             :         MSG_MAP(SetPhyclkVoltageByFreq,         PPSMC_MSG_SetPhyclkVoltageByFreq,       1),
      88             :         MSG_MAP(SetDppclkVoltageByFreq,         PPSMC_MSG_SetDppclkVoltageByFreq,       1),
      89             :         MSG_MAP(SetSoftMinVcn,                  PPSMC_MSG_SetSoftMinVcn,                1),
      90             :         MSG_MAP(EnablePostCode,                 PPSMC_MSG_EnablePostCode,               1),
      91             :         MSG_MAP(GetGfxclkFrequency,             PPSMC_MSG_GetGfxclkFrequency,           1),
      92             :         MSG_MAP(GetFclkFrequency,               PPSMC_MSG_GetFclkFrequency,             1),
      93             :         MSG_MAP(GetMinGfxclkFrequency,          PPSMC_MSG_GetMinGfxclkFrequency,        1),
      94             :         MSG_MAP(GetMaxGfxclkFrequency,          PPSMC_MSG_GetMaxGfxclkFrequency,        1),
      95             :         MSG_MAP(SoftReset,                      PPSMC_MSG_SoftReset,                    1),
      96             :         MSG_MAP(SetGfxCGPG,                     PPSMC_MSG_SetGfxCGPG,                   1),
      97             :         MSG_MAP(SetSoftMaxGfxClk,               PPSMC_MSG_SetSoftMaxGfxClk,             1),
      98             :         MSG_MAP(SetHardMinGfxClk,               PPSMC_MSG_SetHardMinGfxClk,             1),
      99             :         MSG_MAP(SetSoftMaxSocclkByFreq,         PPSMC_MSG_SetSoftMaxSocclkByFreq,       1),
     100             :         MSG_MAP(SetSoftMaxFclkByFreq,           PPSMC_MSG_SetSoftMaxFclkByFreq,         1),
     101             :         MSG_MAP(SetSoftMaxVcn,                  PPSMC_MSG_SetSoftMaxVcn,                1),
     102             :         MSG_MAP(PowerGateMmHub,                 PPSMC_MSG_PowerGateMmHub,               1),
     103             :         MSG_MAP(UpdatePmeRestore,               PPSMC_MSG_UpdatePmeRestore,             1),
     104             :         MSG_MAP(GpuChangeState,                 PPSMC_MSG_GpuChangeState,               1),
     105             :         MSG_MAP(SetPowerLimitPercentage,        PPSMC_MSG_SetPowerLimitPercentage,      1),
     106             :         MSG_MAP(ForceGfxContentSave,            PPSMC_MSG_ForceGfxContentSave,          1),
     107             :         MSG_MAP(EnableTmdp48MHzRefclkPwrDown,   PPSMC_MSG_EnableTmdp48MHzRefclkPwrDown, 1),
     108             :         MSG_MAP(PowerDownJpeg,                  PPSMC_MSG_PowerDownJpeg,                1),
     109             :         MSG_MAP(PowerUpJpeg,                    PPSMC_MSG_PowerUpJpeg,                  1),
     110             :         MSG_MAP(PowerGateAtHub,                 PPSMC_MSG_PowerGateAtHub,               1),
     111             :         MSG_MAP(SetSoftMinJpeg,                 PPSMC_MSG_SetSoftMinJpeg,               1),
     112             :         MSG_MAP(SetHardMinFclkByFreq,           PPSMC_MSG_SetHardMinFclkByFreq,         1),
     113             : };
     114             : 
     115             : static struct cmn2asic_mapping renoir_clk_map[SMU_CLK_COUNT] = {
     116             :         CLK_MAP(GFXCLK, CLOCK_GFXCLK),
     117             :         CLK_MAP(SCLK,   CLOCK_GFXCLK),
     118             :         CLK_MAP(SOCCLK, CLOCK_SOCCLK),
     119             :         CLK_MAP(UCLK, CLOCK_FCLK),
     120             :         CLK_MAP(MCLK, CLOCK_FCLK),
     121             :         CLK_MAP(VCLK, CLOCK_VCLK),
     122             :         CLK_MAP(DCLK, CLOCK_DCLK),
     123             : };
     124             : 
     125             : static struct cmn2asic_mapping renoir_table_map[SMU_TABLE_COUNT] = {
     126             :         TAB_MAP_VALID(WATERMARKS),
     127             :         TAB_MAP_INVALID(CUSTOM_DPM),
     128             :         TAB_MAP_VALID(DPMCLOCKS),
     129             :         TAB_MAP_VALID(SMU_METRICS),
     130             : };
     131             : 
     132             : static struct cmn2asic_mapping renoir_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
     133             :         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D,         WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
     134             :         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,                WORKLOAD_PPLIB_VIDEO_BIT),
     135             :         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR,                   WORKLOAD_PPLIB_VR_BIT),
     136             :         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,              WORKLOAD_PPLIB_COMPUTE_BIT),
     137             :         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,               WORKLOAD_PPLIB_CUSTOM_BIT),
     138             : };
     139             : 
     140             : static const uint8_t renoir_throttler_map[] = {
     141             :         [THROTTLER_STATUS_BIT_SPL]              = (SMU_THROTTLER_SPL_BIT),
     142             :         [THROTTLER_STATUS_BIT_FPPT]             = (SMU_THROTTLER_FPPT_BIT),
     143             :         [THROTTLER_STATUS_BIT_SPPT]             = (SMU_THROTTLER_SPPT_BIT),
     144             :         [THROTTLER_STATUS_BIT_SPPT_APU]         = (SMU_THROTTLER_SPPT_APU_BIT),
     145             :         [THROTTLER_STATUS_BIT_THM_CORE]         = (SMU_THROTTLER_TEMP_CORE_BIT),
     146             :         [THROTTLER_STATUS_BIT_THM_GFX]          = (SMU_THROTTLER_TEMP_GPU_BIT),
     147             :         [THROTTLER_STATUS_BIT_THM_SOC]          = (SMU_THROTTLER_TEMP_SOC_BIT),
     148             :         [THROTTLER_STATUS_BIT_TDC_VDD]          = (SMU_THROTTLER_TDC_VDD_BIT),
     149             :         [THROTTLER_STATUS_BIT_TDC_SOC]          = (SMU_THROTTLER_TDC_SOC_BIT),
     150             :         [THROTTLER_STATUS_BIT_PROCHOT_CPU]      = (SMU_THROTTLER_PROCHOT_CPU_BIT),
     151             :         [THROTTLER_STATUS_BIT_PROCHOT_GFX]      = (SMU_THROTTLER_PROCHOT_GFX_BIT),
     152             :         [THROTTLER_STATUS_BIT_EDC_CPU]          = (SMU_THROTTLER_EDC_CPU_BIT),
     153             :         [THROTTLER_STATUS_BIT_EDC_GFX]          = (SMU_THROTTLER_EDC_GFX_BIT),
     154             : };
     155             : 
     156           0 : static int renoir_init_smc_tables(struct smu_context *smu)
     157             : {
     158           0 :         struct smu_table_context *smu_table = &smu->smu_table;
     159           0 :         struct smu_table *tables = smu_table->tables;
     160             : 
     161           0 :         SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
     162             :                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
     163           0 :         SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),
     164             :                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
     165           0 :         SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
     166             :                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
     167             : 
     168           0 :         smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL);
     169           0 :         if (!smu_table->clocks_table)
     170             :                 goto err0_out;
     171             : 
     172           0 :         smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
     173           0 :         if (!smu_table->metrics_table)
     174             :                 goto err1_out;
     175           0 :         smu_table->metrics_time = 0;
     176             : 
     177           0 :         smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
     178           0 :         if (!smu_table->watermarks_table)
     179             :                 goto err2_out;
     180             : 
     181           0 :         smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
     182           0 :         smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
     183           0 :         if (!smu_table->gpu_metrics_table)
     184             :                 goto err3_out;
     185             : 
     186             :         return 0;
     187             : 
     188             : err3_out:
     189           0 :         kfree(smu_table->watermarks_table);
     190             : err2_out:
     191           0 :         kfree(smu_table->metrics_table);
     192             : err1_out:
     193           0 :         kfree(smu_table->clocks_table);
     194             : err0_out:
     195             :         return -ENOMEM;
     196             : }
     197             : 
     198             : /*
     199             :  * This interface just for getting uclk ultimate freq and should't introduce
     200             :  * other likewise function result in overmuch callback.
     201             :  */
     202           0 : static int renoir_get_dpm_clk_limited(struct smu_context *smu, enum smu_clk_type clk_type,
     203             :                                                 uint32_t dpm_level, uint32_t *freq)
     204             : {
     205           0 :         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
     206             : 
     207           0 :         if (!clk_table || clk_type >= SMU_CLK_COUNT)
     208             :                 return -EINVAL;
     209             : 
     210           0 :         switch (clk_type) {
     211             :         case SMU_SOCCLK:
     212           0 :                 if (dpm_level >= NUM_SOCCLK_DPM_LEVELS)
     213             :                         return -EINVAL;
     214           0 :                 *freq = clk_table->SocClocks[dpm_level].Freq;
     215             :                 break;
     216             :         case SMU_UCLK:
     217             :         case SMU_MCLK:
     218           0 :                 if (dpm_level >= NUM_FCLK_DPM_LEVELS)
     219             :                         return -EINVAL;
     220           0 :                 *freq = clk_table->FClocks[dpm_level].Freq;
     221             :                 break;
     222             :         case SMU_DCEFCLK:
     223           0 :                 if (dpm_level >= NUM_DCFCLK_DPM_LEVELS)
     224             :                         return -EINVAL;
     225           0 :                 *freq = clk_table->DcfClocks[dpm_level].Freq;
     226             :                 break;
     227             :         case SMU_FCLK:
     228           0 :                 if (dpm_level >= NUM_FCLK_DPM_LEVELS)
     229             :                         return -EINVAL;
     230           0 :                 *freq = clk_table->FClocks[dpm_level].Freq;
     231             :                 break;
     232             :         case SMU_VCLK:
     233           0 :                 if (dpm_level >= NUM_VCN_DPM_LEVELS)
     234             :                         return -EINVAL;
     235           0 :                 *freq = clk_table->VClocks[dpm_level].Freq;
     236             :                 break;
     237             :         case SMU_DCLK:
     238           0 :                 if (dpm_level >= NUM_VCN_DPM_LEVELS)
     239             :                         return -EINVAL;
     240           0 :                 *freq = clk_table->DClocks[dpm_level].Freq;
     241             :                 break;
     242             : 
     243             :         default:
     244             :                 return -EINVAL;
     245             :         }
     246             : 
     247             :         return 0;
     248             : }
     249             : 
     250             : static int renoir_get_profiling_clk_mask(struct smu_context *smu,
     251             :                                          enum amd_dpm_forced_level level,
     252             :                                          uint32_t *sclk_mask,
     253             :                                          uint32_t *mclk_mask,
     254             :                                          uint32_t *soc_mask)
     255             : {
     256             : 
     257           0 :         if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
     258             :                 if (sclk_mask)
     259             :                         *sclk_mask = 0;
     260           0 :         } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
     261             :                 if (mclk_mask)
     262             :                         /* mclk levels are in reverse order */
     263             :                         *mclk_mask = NUM_MEMCLK_DPM_LEVELS - 1;
     264           0 :         } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
     265             :                 if(sclk_mask)
     266             :                         /* The sclk as gfxclk and has three level about max/min/current */
     267           0 :                         *sclk_mask = 3 - 1;
     268             : 
     269             :                 if(mclk_mask)
     270             :                         /* mclk levels are in reverse order */
     271           0 :                         *mclk_mask = 0;
     272             : 
     273             :                 if(soc_mask)
     274           0 :                         *soc_mask = NUM_SOCCLK_DPM_LEVELS - 1;
     275             :         }
     276             : 
     277             :         return 0;
     278             : }
     279             : 
     280           0 : static int renoir_get_dpm_ultimate_freq(struct smu_context *smu,
     281             :                                         enum smu_clk_type clk_type,
     282             :                                         uint32_t *min,
     283             :                                         uint32_t *max)
     284             : {
     285           0 :         int ret = 0;
     286             :         uint32_t mclk_mask, soc_mask;
     287             :         uint32_t clock_limit;
     288             : 
     289           0 :         if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) {
     290           0 :                 switch (clk_type) {
     291             :                 case SMU_MCLK:
     292             :                 case SMU_UCLK:
     293           0 :                         clock_limit = smu->smu_table.boot_values.uclk;
     294           0 :                         break;
     295             :                 case SMU_GFXCLK:
     296             :                 case SMU_SCLK:
     297           0 :                         clock_limit = smu->smu_table.boot_values.gfxclk;
     298           0 :                         break;
     299             :                 case SMU_SOCCLK:
     300           0 :                         clock_limit = smu->smu_table.boot_values.socclk;
     301           0 :                         break;
     302             :                 default:
     303             :                         clock_limit = 0;
     304             :                         break;
     305             :                 }
     306             : 
     307             :                 /* clock in Mhz unit */
     308           0 :                 if (min)
     309           0 :                         *min = clock_limit / 100;
     310           0 :                 if (max)
     311           0 :                         *max = clock_limit / 100;
     312             : 
     313             :                 return 0;
     314             :         }
     315             : 
     316           0 :         if (max) {
     317           0 :                 ret = renoir_get_profiling_clk_mask(smu,
     318             :                                                     AMD_DPM_FORCED_LEVEL_PROFILE_PEAK,
     319             :                                                     NULL,
     320             :                                                     &mclk_mask,
     321             :                                                     &soc_mask);
     322             :                 if (ret)
     323             :                         goto failed;
     324             : 
     325             :                 switch (clk_type) {
     326             :                 case SMU_GFXCLK:
     327             :                 case SMU_SCLK:
     328           0 :                         ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMaxGfxclkFrequency, max);
     329           0 :                         if (ret) {
     330           0 :                                 dev_err(smu->adev->dev, "Attempt to get max GX frequency from SMC Failed !\n");
     331           0 :                                 goto failed;
     332             :                         }
     333             :                         break;
     334             :                 case SMU_UCLK:
     335             :                 case SMU_FCLK:
     336             :                 case SMU_MCLK:
     337           0 :                         ret = renoir_get_dpm_clk_limited(smu, clk_type, mclk_mask, max);
     338           0 :                         if (ret)
     339             :                                 goto failed;
     340             :                         break;
     341             :                 case SMU_SOCCLK:
     342           0 :                         ret = renoir_get_dpm_clk_limited(smu, clk_type, soc_mask, max);
     343           0 :                         if (ret)
     344             :                                 goto failed;
     345             :                         break;
     346             :                 default:
     347             :                         ret = -EINVAL;
     348             :                         goto failed;
     349             :                 }
     350             :         }
     351             : 
     352           0 :         if (min) {
     353             :                 switch (clk_type) {
     354             :                 case SMU_GFXCLK:
     355             :                 case SMU_SCLK:
     356           0 :                         ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMinGfxclkFrequency, min);
     357           0 :                         if (ret) {
     358           0 :                                 dev_err(smu->adev->dev, "Attempt to get min GX frequency from SMC Failed !\n");
     359           0 :                                 goto failed;
     360             :                         }
     361             :                         break;
     362             :                 case SMU_UCLK:
     363             :                 case SMU_FCLK:
     364             :                 case SMU_MCLK:
     365           0 :                         ret = renoir_get_dpm_clk_limited(smu, clk_type, NUM_MEMCLK_DPM_LEVELS - 1, min);
     366             :                         if (ret)
     367             :                                 goto failed;
     368             :                         break;
     369             :                 case SMU_SOCCLK:
     370           0 :                         ret = renoir_get_dpm_clk_limited(smu, clk_type, 0, min);
     371             :                         if (ret)
     372             :                                 goto failed;
     373             :                         break;
     374             :                 default:
     375             :                         ret = -EINVAL;
     376             :                         goto failed;
     377             :                 }
     378             :         }
     379             : failed:
     380             :         return ret;
     381             : }
     382             : 
     383           0 : static int renoir_od_edit_dpm_table(struct smu_context *smu,
     384             :                                                         enum PP_OD_DPM_TABLE_COMMAND type,
     385             :                                                         long input[], uint32_t size)
     386             : {
     387           0 :         int ret = 0;
     388           0 :         struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
     389             : 
     390           0 :         if (!(smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL)) {
     391           0 :                 dev_warn(smu->adev->dev,
     392             :                         "pp_od_clk_voltage is not accessible if power_dpm_force_performance_level is not in manual mode!\n");
     393           0 :                 return -EINVAL;
     394             :         }
     395             : 
     396           0 :         switch (type) {
     397             :         case PP_OD_EDIT_SCLK_VDDC_TABLE:
     398           0 :                 if (size != 2) {
     399           0 :                         dev_err(smu->adev->dev, "Input parameter number not correct\n");
     400           0 :                         return -EINVAL;
     401             :                 }
     402             : 
     403           0 :                 if (input[0] == 0) {
     404           0 :                         if (input[1] < smu->gfx_default_hard_min_freq) {
     405           0 :                                 dev_warn(smu->adev->dev,
     406             :                                         "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
     407             :                                         input[1], smu->gfx_default_hard_min_freq);
     408           0 :                                 return -EINVAL;
     409             :                         }
     410           0 :                         smu->gfx_actual_hard_min_freq = input[1];
     411           0 :                 } else if (input[0] == 1) {
     412           0 :                         if (input[1] > smu->gfx_default_soft_max_freq) {
     413           0 :                                 dev_warn(smu->adev->dev,
     414             :                                         "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
     415             :                                         input[1], smu->gfx_default_soft_max_freq);
     416           0 :                                 return -EINVAL;
     417             :                         }
     418           0 :                         smu->gfx_actual_soft_max_freq = input[1];
     419             :                 } else {
     420             :                         return -EINVAL;
     421             :                 }
     422             :                 break;
     423             :         case PP_OD_RESTORE_DEFAULT_TABLE:
     424           0 :                 if (size != 0) {
     425           0 :                         dev_err(smu->adev->dev, "Input parameter number not correct\n");
     426           0 :                         return -EINVAL;
     427             :                 }
     428           0 :                 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
     429           0 :                 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
     430           0 :                 break;
     431             :         case PP_OD_COMMIT_DPM_TABLE:
     432           0 :                 if (size != 0) {
     433           0 :                         dev_err(smu->adev->dev, "Input parameter number not correct\n");
     434           0 :                         return -EINVAL;
     435             :                 } else {
     436           0 :                         if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) {
     437           0 :                                 dev_err(smu->adev->dev,
     438             :                                         "The setting minimum sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
     439             :                                         smu->gfx_actual_hard_min_freq,
     440             :                                         smu->gfx_actual_soft_max_freq);
     441           0 :                                 return -EINVAL;
     442             :                         }
     443             : 
     444           0 :                         ret = smu_cmn_send_smc_msg_with_param(smu,
     445             :                                                                 SMU_MSG_SetHardMinGfxClk,
     446             :                                                                 smu->gfx_actual_hard_min_freq,
     447             :                                                                 NULL);
     448           0 :                         if (ret) {
     449           0 :                                 dev_err(smu->adev->dev, "Set hard min sclk failed!");
     450           0 :                                 return ret;
     451             :                         }
     452             : 
     453           0 :                         ret = smu_cmn_send_smc_msg_with_param(smu,
     454             :                                                                 SMU_MSG_SetSoftMaxGfxClk,
     455             :                                                                 smu->gfx_actual_soft_max_freq,
     456             :                                                                 NULL);
     457           0 :                         if (ret) {
     458           0 :                                 dev_err(smu->adev->dev, "Set soft max sclk failed!");
     459           0 :                                 return ret;
     460             :                         }
     461             :                 }
     462             :                 break;
     463             :         default:
     464             :                 return -ENOSYS;
     465             :         }
     466             : 
     467             :         return ret;
     468             : }
     469             : 
     470           0 : static int renoir_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
     471             : {
     472           0 :         uint32_t min = 0, max = 0;
     473           0 :         uint32_t ret = 0;
     474             : 
     475           0 :         ret = smu_cmn_send_smc_msg_with_param(smu,
     476             :                                                                 SMU_MSG_GetMinGfxclkFrequency,
     477             :                                                                 0, &min);
     478           0 :         if (ret)
     479             :                 return ret;
     480           0 :         ret = smu_cmn_send_smc_msg_with_param(smu,
     481             :                                                                 SMU_MSG_GetMaxGfxclkFrequency,
     482             :                                                                 0, &max);
     483           0 :         if (ret)
     484             :                 return ret;
     485             : 
     486           0 :         smu->gfx_default_hard_min_freq = min;
     487           0 :         smu->gfx_default_soft_max_freq = max;
     488           0 :         smu->gfx_actual_hard_min_freq = 0;
     489           0 :         smu->gfx_actual_soft_max_freq = 0;
     490             : 
     491           0 :         return 0;
     492             : }
     493             : 
     494           0 : static int renoir_print_clk_levels(struct smu_context *smu,
     495             :                         enum smu_clk_type clk_type, char *buf)
     496             : {
     497           0 :         int i, size = 0, ret = 0;
     498           0 :         uint32_t cur_value = 0, value = 0, count = 0, min = 0, max = 0;
     499             :         SmuMetrics_t metrics;
     500           0 :         struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
     501           0 :         bool cur_value_match_level = false;
     502             : 
     503           0 :         memset(&metrics, 0, sizeof(metrics));
     504             : 
     505           0 :         ret = smu_cmn_get_metrics_table(smu, &metrics, false);
     506           0 :         if (ret)
     507             :                 return ret;
     508             : 
     509           0 :         smu_cmn_get_sysfs_buf(&buf, &size);
     510             : 
     511           0 :         switch (clk_type) {
     512             :         case SMU_OD_RANGE:
     513           0 :                 if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
     514           0 :                         ret = smu_cmn_send_smc_msg_with_param(smu,
     515             :                                                 SMU_MSG_GetMinGfxclkFrequency,
     516             :                                                 0, &min);
     517           0 :                         if (ret)
     518             :                                 return ret;
     519           0 :                         ret = smu_cmn_send_smc_msg_with_param(smu,
     520             :                                                 SMU_MSG_GetMaxGfxclkFrequency,
     521             :                                                 0, &max);
     522           0 :                         if (ret)
     523             :                                 return ret;
     524           0 :                         size += sysfs_emit_at(buf, size, "OD_RANGE\nSCLK: %10uMhz %10uMhz\n", min, max);
     525             :                 }
     526             :                 break;
     527             :         case SMU_OD_SCLK:
     528           0 :                 if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
     529           0 :                         min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
     530           0 :                         max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
     531           0 :                         size += sysfs_emit_at(buf, size, "OD_SCLK\n");
     532           0 :                         size += sysfs_emit_at(buf, size, "0:%10uMhz\n", min);
     533           0 :                         size += sysfs_emit_at(buf, size, "1:%10uMhz\n", max);
     534             :                 }
     535             :                 break;
     536             :         case SMU_GFXCLK:
     537             :         case SMU_SCLK:
     538             :                 /* retirve table returned paramters unit is MHz */
     539           0 :                 cur_value = metrics.ClockFrequency[CLOCK_GFXCLK];
     540           0 :                 ret = renoir_get_dpm_ultimate_freq(smu, SMU_GFXCLK, &min, &max);
     541           0 :                 if (!ret) {
     542             :                         /* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
     543           0 :                         if (cur_value  == max)
     544             :                                 i = 2;
     545           0 :                         else if (cur_value == min)
     546             :                                 i = 0;
     547             :                         else
     548           0 :                                 i = 1;
     549             : 
     550           0 :                         size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
     551             :                                         i == 0 ? "*" : "");
     552           0 :                         size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
     553             :                                         i == 1 ? cur_value : RENOIR_UMD_PSTATE_GFXCLK,
     554             :                                         i == 1 ? "*" : "");
     555           0 :                         size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
     556             :                                         i == 2 ? "*" : "");
     557             :                 }
     558             :                 return size;
     559             :         case SMU_SOCCLK:
     560           0 :                 count = NUM_SOCCLK_DPM_LEVELS;
     561           0 :                 cur_value = metrics.ClockFrequency[CLOCK_SOCCLK];
     562           0 :                 break;
     563             :         case SMU_MCLK:
     564           0 :                 count = NUM_MEMCLK_DPM_LEVELS;
     565           0 :                 cur_value = metrics.ClockFrequency[CLOCK_FCLK];
     566           0 :                 break;
     567             :         case SMU_DCEFCLK:
     568           0 :                 count = NUM_DCFCLK_DPM_LEVELS;
     569           0 :                 cur_value = metrics.ClockFrequency[CLOCK_DCFCLK];
     570           0 :                 break;
     571             :         case SMU_FCLK:
     572           0 :                 count = NUM_FCLK_DPM_LEVELS;
     573           0 :                 cur_value = metrics.ClockFrequency[CLOCK_FCLK];
     574           0 :                 break;
     575             :         case SMU_VCLK:
     576           0 :                 count = NUM_VCN_DPM_LEVELS;
     577           0 :                 cur_value = metrics.ClockFrequency[CLOCK_VCLK];
     578           0 :                 break;
     579             :         case SMU_DCLK:
     580           0 :                 count = NUM_VCN_DPM_LEVELS;
     581           0 :                 cur_value = metrics.ClockFrequency[CLOCK_DCLK];
     582           0 :                 break;
     583             :         default:
     584             :                 break;
     585             :         }
     586             : 
     587             :         switch (clk_type) {
     588             :         case SMU_GFXCLK:
     589             :         case SMU_SCLK:
     590             :         case SMU_SOCCLK:
     591             :         case SMU_MCLK:
     592             :         case SMU_DCEFCLK:
     593             :         case SMU_FCLK:
     594             :         case SMU_VCLK:
     595             :         case SMU_DCLK:
     596           0 :                 for (i = 0; i < count; i++) {
     597           0 :                         ret = renoir_get_dpm_clk_limited(smu, clk_type, i, &value);
     598           0 :                         if (ret)
     599             :                                 return ret;
     600           0 :                         if (!value)
     601           0 :                                 continue;
     602           0 :                         size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value,
     603             :                                         cur_value == value ? "*" : "");
     604           0 :                         if (cur_value == value)
     605           0 :                                 cur_value_match_level = true;
     606             :                 }
     607             : 
     608           0 :                 if (!cur_value_match_level)
     609           0 :                         size += sysfs_emit_at(buf, size, "   %uMhz *\n", cur_value);
     610             : 
     611             :                 break;
     612             :         default:
     613             :                 break;
     614             :         }
     615             : 
     616             :         return size;
     617             : }
     618             : 
     619           0 : static enum amd_pm_state_type renoir_get_current_power_state(struct smu_context *smu)
     620             : {
     621             :         enum amd_pm_state_type pm_type;
     622           0 :         struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
     623             : 
     624           0 :         if (!smu_dpm_ctx->dpm_context ||
     625           0 :             !smu_dpm_ctx->dpm_current_power_state)
     626             :                 return -EINVAL;
     627             : 
     628           0 :         switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
     629             :         case SMU_STATE_UI_LABEL_BATTERY:
     630             :                 pm_type = POWER_STATE_TYPE_BATTERY;
     631             :                 break;
     632             :         case SMU_STATE_UI_LABEL_BALLANCED:
     633           0 :                 pm_type = POWER_STATE_TYPE_BALANCED;
     634           0 :                 break;
     635             :         case SMU_STATE_UI_LABEL_PERFORMANCE:
     636           0 :                 pm_type = POWER_STATE_TYPE_PERFORMANCE;
     637           0 :                 break;
     638             :         default:
     639           0 :                 if (smu_dpm_ctx->dpm_current_power_state->classification.flags & SMU_STATE_CLASSIFICATION_FLAG_BOOT)
     640             :                         pm_type = POWER_STATE_TYPE_INTERNAL_BOOT;
     641             :                 else
     642           0 :                         pm_type = POWER_STATE_TYPE_DEFAULT;
     643             :                 break;
     644             :         }
     645             : 
     646             :         return pm_type;
     647             : }
     648             : 
     649           0 : static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
     650             : {
     651           0 :         int ret = 0;
     652             : 
     653           0 :         if (enable) {
     654             :                 /* vcn dpm on is a prerequisite for vcn power gate messages */
     655           0 :                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
     656           0 :                         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL);
     657           0 :                         if (ret)
     658             :                                 return ret;
     659             :                 }
     660             :         } else {
     661           0 :                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
     662           0 :                         ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
     663           0 :                         if (ret)
     664             :                                 return ret;
     665             :                 }
     666             :         }
     667             : 
     668             :         return ret;
     669             : }
     670             : 
     671           0 : static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
     672             : {
     673           0 :         int ret = 0;
     674             : 
     675           0 :         if (enable) {
     676           0 :                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
     677           0 :                         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpJpeg, 0, NULL);
     678           0 :                         if (ret)
     679             :                                 return ret;
     680             :                 }
     681             :         } else {
     682           0 :                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
     683           0 :                         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL);
     684           0 :                         if (ret)
     685             :                                 return ret;
     686             :                 }
     687             :         }
     688             : 
     689             :         return ret;
     690             : }
     691             : 
     692           0 : static int renoir_force_dpm_limit_value(struct smu_context *smu, bool highest)
     693             : {
     694           0 :         int ret = 0, i = 0;
     695             :         uint32_t min_freq, max_freq, force_freq;
     696             :         enum smu_clk_type clk_type;
     697             : 
     698           0 :         enum smu_clk_type clks[] = {
     699             :                 SMU_GFXCLK,
     700             :                 SMU_MCLK,
     701             :                 SMU_SOCCLK,
     702             :         };
     703             : 
     704           0 :         for (i = 0; i < ARRAY_SIZE(clks); i++) {
     705           0 :                 clk_type = clks[i];
     706           0 :                 ret = renoir_get_dpm_ultimate_freq(smu, clk_type, &min_freq, &max_freq);
     707           0 :                 if (ret)
     708             :                         return ret;
     709             : 
     710           0 :                 force_freq = highest ? max_freq : min_freq;
     711           0 :                 ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq);
     712           0 :                 if (ret)
     713             :                         return ret;
     714             :         }
     715             : 
     716             :         return ret;
     717             : }
     718             : 
     719           0 : static int renoir_unforce_dpm_levels(struct smu_context *smu) {
     720             : 
     721           0 :         int ret = 0, i = 0;
     722             :         uint32_t min_freq, max_freq;
     723             :         enum smu_clk_type clk_type;
     724             : 
     725             :         struct clk_feature_map {
     726             :                 enum smu_clk_type clk_type;
     727             :                 uint32_t        feature;
     728           0 :         } clk_feature_map[] = {
     729             :                 {SMU_GFXCLK, SMU_FEATURE_DPM_GFXCLK_BIT},
     730             :                 {SMU_MCLK,   SMU_FEATURE_DPM_UCLK_BIT},
     731             :                 {SMU_SOCCLK, SMU_FEATURE_DPM_SOCCLK_BIT},
     732             :         };
     733             : 
     734           0 :         for (i = 0; i < ARRAY_SIZE(clk_feature_map); i++) {
     735           0 :                 if (!smu_cmn_feature_is_enabled(smu, clk_feature_map[i].feature))
     736           0 :                     continue;
     737             : 
     738           0 :                 clk_type = clk_feature_map[i].clk_type;
     739             : 
     740           0 :                 ret = renoir_get_dpm_ultimate_freq(smu, clk_type, &min_freq, &max_freq);
     741           0 :                 if (ret)
     742             :                         return ret;
     743             : 
     744           0 :                 ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
     745           0 :                 if (ret)
     746             :                         return ret;
     747             :         }
     748             : 
     749             :         return ret;
     750             : }
     751             : 
     752             : /*
     753             :  * This interface get dpm clock table for dc
     754             :  */
     755           0 : static int renoir_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks *clock_table)
     756             : {
     757           0 :         DpmClocks_t *table = smu->smu_table.clocks_table;
     758             :         int i;
     759             : 
     760           0 :         if (!clock_table || !table)
     761             :                 return -EINVAL;
     762             : 
     763           0 :         for (i = 0; i < NUM_DCFCLK_DPM_LEVELS; i++) {
     764           0 :                 clock_table->DcfClocks[i].Freq = table->DcfClocks[i].Freq;
     765           0 :                 clock_table->DcfClocks[i].Vol = table->DcfClocks[i].Vol;
     766             :         }
     767             : 
     768           0 :         for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) {
     769           0 :                 clock_table->SocClocks[i].Freq = table->SocClocks[i].Freq;
     770           0 :                 clock_table->SocClocks[i].Vol = table->SocClocks[i].Vol;
     771             :         }
     772             : 
     773           0 :         for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) {
     774           0 :                 clock_table->FClocks[i].Freq = table->FClocks[i].Freq;
     775           0 :                 clock_table->FClocks[i].Vol = table->FClocks[i].Vol;
     776             :         }
     777             : 
     778           0 :         for (i = 0; i<  NUM_MEMCLK_DPM_LEVELS; i++) {
     779           0 :                 clock_table->MemClocks[i].Freq = table->MemClocks[i].Freq;
     780           0 :                 clock_table->MemClocks[i].Vol = table->MemClocks[i].Vol;
     781             :         }
     782             : 
     783           0 :         for (i = 0; i < NUM_VCN_DPM_LEVELS; i++) {
     784           0 :                 clock_table->VClocks[i].Freq = table->VClocks[i].Freq;
     785           0 :                 clock_table->VClocks[i].Vol = table->VClocks[i].Vol;
     786             :         }
     787             : 
     788           0 :         for (i = 0; i < NUM_VCN_DPM_LEVELS; i++) {
     789           0 :                 clock_table->DClocks[i].Freq = table->DClocks[i].Freq;
     790           0 :                 clock_table->DClocks[i].Vol = table->DClocks[i].Vol;
     791             :         }
     792             : 
     793             :         return 0;
     794             : }
     795             : 
     796           0 : static int renoir_force_clk_levels(struct smu_context *smu,
     797             :                                    enum smu_clk_type clk_type, uint32_t mask)
     798             : {
     799             : 
     800           0 :         int ret = 0 ;
     801           0 :         uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0;
     802             : 
     803           0 :         soft_min_level = mask ? (ffs(mask) - 1) : 0;
     804           0 :         soft_max_level = mask ? (fls(mask) - 1) : 0;
     805             : 
     806           0 :         switch (clk_type) {
     807             :         case SMU_GFXCLK:
     808             :         case SMU_SCLK:
     809           0 :                 if (soft_min_level > 2 || soft_max_level > 2) {
     810           0 :                         dev_info(smu->adev->dev, "Currently sclk only support 3 levels on APU\n");
     811           0 :                         return -EINVAL;
     812             :                 }
     813             : 
     814           0 :                 ret = renoir_get_dpm_ultimate_freq(smu, SMU_GFXCLK, &min_freq, &max_freq);
     815           0 :                 if (ret)
     816             :                         return ret;
     817           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
     818             :                                         soft_max_level == 0 ? min_freq :
     819           0 :                                         soft_max_level == 1 ? RENOIR_UMD_PSTATE_GFXCLK : max_freq,
     820             :                                         NULL);
     821           0 :                 if (ret)
     822             :                         return ret;
     823           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
     824             :                                         soft_min_level == 2 ? max_freq :
     825           0 :                                         soft_min_level == 1 ? RENOIR_UMD_PSTATE_GFXCLK : min_freq,
     826             :                                         NULL);
     827             :                 if (ret)
     828             :                         return ret;
     829             :                 break;
     830             :         case SMU_SOCCLK:
     831           0 :                 ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_min_level, &min_freq);
     832           0 :                 if (ret)
     833             :                         return ret;
     834           0 :                 ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_max_level, &max_freq);
     835           0 :                 if (ret)
     836             :                         return ret;
     837           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxSocclkByFreq, max_freq, NULL);
     838           0 :                 if (ret)
     839             :                         return ret;
     840           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinSocclkByFreq, min_freq, NULL);
     841             :                 if (ret)
     842             :                         return ret;
     843             :                 break;
     844             :         case SMU_MCLK:
     845             :         case SMU_FCLK:
     846           0 :                 ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_min_level, &min_freq);
     847           0 :                 if (ret)
     848             :                         return ret;
     849           0 :                 ret = renoir_get_dpm_clk_limited(smu, clk_type, soft_max_level, &max_freq);
     850           0 :                 if (ret)
     851             :                         return ret;
     852           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxFclkByFreq, max_freq, NULL);
     853           0 :                 if (ret)
     854             :                         return ret;
     855           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinFclkByFreq, min_freq, NULL);
     856             :                 if (ret)
     857             :                         return ret;
     858             :                 break;
     859             :         default:
     860             :                 break;
     861             :         }
     862             : 
     863             :         return ret;
     864             : }
     865             : 
     866           0 : static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
     867             : {
     868             :         int workload_type, ret;
     869           0 :         uint32_t profile_mode = input[size];
     870             : 
     871           0 :         if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
     872           0 :                 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);
     873           0 :                 return -EINVAL;
     874             :         }
     875             : 
     876           0 :         if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT ||
     877           0 :                         profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)
     878             :                 return 0;
     879             : 
     880             :         /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
     881           0 :         workload_type = smu_cmn_to_asic_specific_index(smu,
     882             :                                                        CMN2ASIC_MAPPING_WORKLOAD,
     883             :                                                        profile_mode);
     884           0 :         if (workload_type < 0) {
     885             :                 /*
     886             :                  * TODO: If some case need switch to powersave/default power mode
     887             :                  * then can consider enter WORKLOAD_COMPUTE/WORKLOAD_CUSTOM for power saving.
     888             :                  */
     889             :                 dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on RENOIR\n", profile_mode);
     890             :                 return -EINVAL;
     891             :         }
     892             : 
     893           0 :         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
     894           0 :                                     1 << workload_type,
     895             :                                     NULL);
     896           0 :         if (ret) {
     897           0 :                 dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", workload_type);
     898             :                 return ret;
     899             :         }
     900             : 
     901           0 :         smu->power_profile_mode = profile_mode;
     902             : 
     903           0 :         return 0;
     904             : }
     905             : 
     906           0 : static int renoir_set_peak_clock_by_device(struct smu_context *smu)
     907             : {
     908           0 :         int ret = 0;
     909           0 :         uint32_t sclk_freq = 0, uclk_freq = 0;
     910             : 
     911           0 :         ret = renoir_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_freq);
     912           0 :         if (ret)
     913             :                 return ret;
     914             : 
     915           0 :         ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk_freq, sclk_freq);
     916           0 :         if (ret)
     917             :                 return ret;
     918             : 
     919           0 :         ret = renoir_get_dpm_ultimate_freq(smu, SMU_UCLK, NULL, &uclk_freq);
     920           0 :         if (ret)
     921             :                 return ret;
     922             : 
     923           0 :         ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_UCLK, uclk_freq, uclk_freq);
     924             :         if (ret)
     925             :                 return ret;
     926             : 
     927             :         return ret;
     928             : }
     929             : 
     930           0 : static int renoir_set_performance_level(struct smu_context *smu,
     931             :                                         enum amd_dpm_forced_level level)
     932             : {
     933           0 :         int ret = 0;
     934             :         uint32_t sclk_mask, mclk_mask, soc_mask;
     935             : 
     936           0 :         switch (level) {
     937             :         case AMD_DPM_FORCED_LEVEL_HIGH:
     938           0 :                 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
     939           0 :                 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
     940             : 
     941           0 :                 ret = renoir_force_dpm_limit_value(smu, true);
     942           0 :                 break;
     943             :         case AMD_DPM_FORCED_LEVEL_LOW:
     944           0 :                 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
     945           0 :                 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
     946             : 
     947           0 :                 ret = renoir_force_dpm_limit_value(smu, false);
     948           0 :                 break;
     949             :         case AMD_DPM_FORCED_LEVEL_AUTO:
     950           0 :                 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
     951           0 :                 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
     952             : 
     953           0 :                 ret = renoir_unforce_dpm_levels(smu);
     954           0 :                 break;
     955             :         case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
     956           0 :                 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
     957           0 :                 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
     958             : 
     959           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu,
     960             :                                                       SMU_MSG_SetHardMinGfxClk,
     961             :                                                       RENOIR_UMD_PSTATE_GFXCLK,
     962             :                                                       NULL);
     963           0 :                 if (ret)
     964             :                         return ret;
     965           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu,
     966             :                                                       SMU_MSG_SetHardMinFclkByFreq,
     967             :                                                       RENOIR_UMD_PSTATE_FCLK,
     968             :                                                       NULL);
     969           0 :                 if (ret)
     970             :                         return ret;
     971           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu,
     972             :                                                       SMU_MSG_SetHardMinSocclkByFreq,
     973             :                                                       RENOIR_UMD_PSTATE_SOCCLK,
     974             :                                                       NULL);
     975           0 :                 if (ret)
     976             :                         return ret;
     977           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu,
     978             :                                                       SMU_MSG_SetHardMinVcn,
     979             :                                                       RENOIR_UMD_PSTATE_VCNCLK,
     980             :                                                       NULL);
     981           0 :                 if (ret)
     982             :                         return ret;
     983             : 
     984           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu,
     985             :                                                       SMU_MSG_SetSoftMaxGfxClk,
     986             :                                                       RENOIR_UMD_PSTATE_GFXCLK,
     987             :                                                       NULL);
     988           0 :                 if (ret)
     989             :                         return ret;
     990           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu,
     991             :                                                       SMU_MSG_SetSoftMaxFclkByFreq,
     992             :                                                       RENOIR_UMD_PSTATE_FCLK,
     993             :                                                       NULL);
     994           0 :                 if (ret)
     995             :                         return ret;
     996           0 :                 ret = smu_cmn_send_smc_msg_with_param(smu,
     997             :                                                       SMU_MSG_SetSoftMaxSocclkByFreq,
     998             :                                                       RENOIR_UMD_PSTATE_SOCCLK,
     999             :                                                       NULL);
    1000           0 :                 if (ret)
    1001             :                         return ret;
    1002           0 :                 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           0 :                 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
    1012           0 :                 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
    1013             : 
    1014           0 :                 ret = renoir_get_profiling_clk_mask(smu, level,
    1015             :                                                     &sclk_mask,
    1016             :                                                     &mclk_mask,
    1017             :                                                     &soc_mask);
    1018             :                 if (ret)
    1019             :                         return ret;
    1020           0 :                 renoir_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask);
    1021           0 :                 renoir_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask);
    1022           0 :                 renoir_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
    1023           0 :                 break;
    1024             :         case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
    1025           0 :                 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
    1026           0 :                 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
    1027             : 
    1028           0 :                 ret = renoir_set_peak_clock_by_device(smu);
    1029           0 :                 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           0 : static int renoir_set_watermarks_table(
    1042             :                 struct smu_context *smu,
    1043             :                 struct pp_smu_wm_range_sets *clock_ranges)
    1044             : {
    1045           0 :         Watermarks_t *table = smu->smu_table.watermarks_table;
    1046           0 :         int ret = 0;
    1047             :         int i;
    1048             : 
    1049           0 :         if (clock_ranges) {
    1050           0 :                 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES ||
    1051           0 :                     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           0 :                 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
    1056           0 :                         table->WatermarkRow[WM_DCFCLK][i].MinClock =
    1057           0 :                                 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
    1058           0 :                         table->WatermarkRow[WM_DCFCLK][i].MaxClock =
    1059           0 :                                 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
    1060           0 :                         table->WatermarkRow[WM_DCFCLK][i].MinMclk =
    1061           0 :                                 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
    1062           0 :                         table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
    1063           0 :                                 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
    1064             : 
    1065           0 :                         table->WatermarkRow[WM_DCFCLK][i].WmSetting =
    1066           0 :                                 clock_ranges->reader_wm_sets[i].wm_inst;
    1067           0 :                         table->WatermarkRow[WM_DCFCLK][i].WmType =
    1068           0 :                                 clock_ranges->reader_wm_sets[i].wm_type;
    1069             :                 }
    1070             : 
    1071           0 :                 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
    1072           0 :                         table->WatermarkRow[WM_SOCCLK][i].MinClock =
    1073           0 :                                 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
    1074           0 :                         table->WatermarkRow[WM_SOCCLK][i].MaxClock =
    1075           0 :                                 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
    1076           0 :                         table->WatermarkRow[WM_SOCCLK][i].MinMclk =
    1077           0 :                                 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
    1078           0 :                         table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
    1079           0 :                                 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
    1080             : 
    1081           0 :                         table->WatermarkRow[WM_SOCCLK][i].WmSetting =
    1082           0 :                                 clock_ranges->writer_wm_sets[i].wm_inst;
    1083           0 :                         table->WatermarkRow[WM_SOCCLK][i].WmType =
    1084           0 :                                 clock_ranges->writer_wm_sets[i].wm_type;
    1085             :                 }
    1086             : 
    1087           0 :                 smu->watermarks_bitmap |= WATERMARKS_EXIST;
    1088             :         }
    1089             : 
    1090             :         /* pass data to smu controller */
    1091           0 :         if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
    1092             :              !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
    1093           0 :                 ret = smu_cmn_write_watermarks_table(smu);
    1094           0 :                 if (ret) {
    1095           0 :                         dev_err(smu->adev->dev, "Failed to update WMTABLE!");
    1096           0 :                         return ret;
    1097             :                 }
    1098           0 :                 smu->watermarks_bitmap |= WATERMARKS_LOADED;
    1099             :         }
    1100             : 
    1101             :         return 0;
    1102             : }
    1103             : 
    1104           0 : static int renoir_get_power_profile_mode(struct smu_context *smu,
    1105             :                                            char *buf)
    1106             : {
    1107           0 :         uint32_t i, size = 0;
    1108           0 :         int16_t workload_type = 0;
    1109             : 
    1110           0 :         if (!buf)
    1111             :                 return -EINVAL;
    1112             : 
    1113           0 :         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           0 :                 workload_type = smu_cmn_to_asic_specific_index(smu,
    1119             :                                                                CMN2ASIC_MAPPING_WORKLOAD,
    1120             :                                                                i);
    1121           0 :                 if (workload_type < 0)
    1122           0 :                         continue;
    1123             : 
    1124           0 :                 size += sysfs_emit_at(buf, size, "%2d %14s%s\n",
    1125           0 :                         i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
    1126             :         }
    1127             : 
    1128           0 :         return size;
    1129             : }
    1130             : 
    1131           0 : static void renoir_get_ss_power_percent(SmuMetrics_t *metrics,
    1132             :                                         uint32_t *apu_percent, uint32_t *dgpu_percent)
    1133             : {
    1134           0 :         uint32_t apu_boost = 0;
    1135           0 :         uint32_t dgpu_boost = 0;
    1136           0 :         uint16_t apu_limit = 0;
    1137           0 :         uint16_t dgpu_limit = 0;
    1138           0 :         uint16_t apu_power = 0;
    1139           0 :         uint16_t dgpu_power = 0;
    1140             : 
    1141           0 :         apu_power = metrics->ApuPower;
    1142           0 :         apu_limit = metrics->StapmOriginalLimit;
    1143           0 :         if (apu_power > apu_limit && apu_limit != 0)
    1144           0 :                 apu_boost =  ((apu_power - apu_limit) * 100) / apu_limit;
    1145           0 :         apu_boost = (apu_boost > 100) ? 100 : apu_boost;
    1146             : 
    1147           0 :         dgpu_power = metrics->dGpuPower;
    1148           0 :         if (metrics->StapmCurrentLimit > metrics->StapmOriginalLimit)
    1149           0 :                 dgpu_limit = metrics->StapmCurrentLimit - metrics->StapmOriginalLimit;
    1150           0 :         if (dgpu_power > dgpu_limit && dgpu_limit != 0)
    1151           0 :                 dgpu_boost = ((dgpu_power - dgpu_limit) * 100) / dgpu_limit;
    1152           0 :         dgpu_boost = (dgpu_boost > 100) ? 100 : dgpu_boost;
    1153             : 
    1154           0 :         if (dgpu_boost >= apu_boost)
    1155             :                 apu_boost = 0;
    1156             :         else
    1157           0 :                 dgpu_boost = 0;
    1158             : 
    1159           0 :         *apu_percent = apu_boost;
    1160           0 :         *dgpu_percent = dgpu_boost;
    1161           0 : }
    1162             : 
    1163             : 
    1164           0 : static int renoir_get_smu_metrics_data(struct smu_context *smu,
    1165             :                                        MetricsMember_t member,
    1166             :                                        uint32_t *value)
    1167             : {
    1168           0 :         struct smu_table_context *smu_table = &smu->smu_table;
    1169             : 
    1170           0 :         SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
    1171           0 :         int ret = 0;
    1172           0 :         uint32_t apu_percent = 0;
    1173           0 :         uint32_t dgpu_percent = 0;
    1174             : 
    1175             : 
    1176           0 :         ret = smu_cmn_get_metrics_table(smu,
    1177             :                                         NULL,
    1178             :                                         false);
    1179           0 :         if (ret)
    1180             :                 return ret;
    1181             : 
    1182           0 :         switch (member) {
    1183             :         case METRICS_AVERAGE_GFXCLK:
    1184           0 :                 *value = metrics->ClockFrequency[CLOCK_GFXCLK];
    1185           0 :                 break;
    1186             :         case METRICS_AVERAGE_SOCCLK:
    1187           0 :                 *value = metrics->ClockFrequency[CLOCK_SOCCLK];
    1188           0 :                 break;
    1189             :         case METRICS_AVERAGE_UCLK:
    1190           0 :                 *value = metrics->ClockFrequency[CLOCK_FCLK];
    1191           0 :                 break;
    1192             :         case METRICS_AVERAGE_GFXACTIVITY:
    1193           0 :                 *value = metrics->AverageGfxActivity / 100;
    1194           0 :                 break;
    1195             :         case METRICS_AVERAGE_VCNACTIVITY:
    1196           0 :                 *value = metrics->AverageUvdActivity / 100;
    1197           0 :                 break;
    1198             :         case METRICS_AVERAGE_SOCKETPOWER:
    1199           0 :                 *value = (metrics->CurrentSocketPower << 8) / 1000;
    1200           0 :                 break;
    1201             :         case METRICS_TEMPERATURE_EDGE:
    1202           0 :                 *value = (metrics->GfxTemperature / 100) *
    1203             :                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
    1204           0 :                 break;
    1205             :         case METRICS_TEMPERATURE_HOTSPOT:
    1206           0 :                 *value = (metrics->SocTemperature / 100) *
    1207             :                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
    1208           0 :                 break;
    1209             :         case METRICS_THROTTLER_STATUS:
    1210           0 :                 *value = metrics->ThrottlerStatus;
    1211           0 :                 break;
    1212             :         case METRICS_VOLTAGE_VDDGFX:
    1213           0 :                 *value = metrics->Voltage[0];
    1214           0 :                 break;
    1215             :         case METRICS_VOLTAGE_VDDSOC:
    1216           0 :                 *value = metrics->Voltage[1];
    1217           0 :                 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           0 :                 renoir_get_ss_power_percent(metrics, &apu_percent, &dgpu_percent);
    1223           0 :                 *value = apu_percent;
    1224           0 :                 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           0 :                 renoir_get_ss_power_percent(metrics, &apu_percent, &dgpu_percent);
    1230           0 :                 *value = dgpu_percent;
    1231           0 :                 break;
    1232             :         default:
    1233           0 :                 *value = UINT_MAX;
    1234           0 :                 break;
    1235             :         }
    1236             : 
    1237             :         return ret;
    1238             : }
    1239             : 
    1240           0 : static int renoir_read_sensor(struct smu_context *smu,
    1241             :                                  enum amd_pp_sensors sensor,
    1242             :                                  void *data, uint32_t *size)
    1243             : {
    1244           0 :         int ret = 0;
    1245             : 
    1246           0 :         if (!data || !size)
    1247             :                 return -EINVAL;
    1248             : 
    1249           0 :         switch (sensor) {
    1250             :         case AMDGPU_PP_SENSOR_GPU_LOAD:
    1251           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1252             :                                                   METRICS_AVERAGE_GFXACTIVITY,
    1253             :                                                   (uint32_t *)data);
    1254           0 :                 *size = 4;
    1255           0 :                 break;
    1256             :         case AMDGPU_PP_SENSOR_EDGE_TEMP:
    1257           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1258             :                                                   METRICS_TEMPERATURE_EDGE,
    1259             :                                                   (uint32_t *)data);
    1260           0 :                 *size = 4;
    1261           0 :                 break;
    1262             :         case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
    1263           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1264             :                                                   METRICS_TEMPERATURE_HOTSPOT,
    1265             :                                                   (uint32_t *)data);
    1266           0 :                 *size = 4;
    1267           0 :                 break;
    1268             :         case AMDGPU_PP_SENSOR_GFX_MCLK:
    1269           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1270             :                                                   METRICS_AVERAGE_UCLK,
    1271             :                                                   (uint32_t *)data);
    1272           0 :                 *(uint32_t *)data *= 100;
    1273           0 :                 *size = 4;
    1274           0 :                 break;
    1275             :         case AMDGPU_PP_SENSOR_GFX_SCLK:
    1276           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1277             :                                                   METRICS_AVERAGE_GFXCLK,
    1278             :                                                   (uint32_t *)data);
    1279           0 :                 *(uint32_t *)data *= 100;
    1280           0 :                 *size = 4;
    1281           0 :                 break;
    1282             :         case AMDGPU_PP_SENSOR_VDDGFX:
    1283           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1284             :                                                   METRICS_VOLTAGE_VDDGFX,
    1285             :                                                   (uint32_t *)data);
    1286           0 :                 *size = 4;
    1287           0 :                 break;
    1288             :         case AMDGPU_PP_SENSOR_VDDNB:
    1289           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1290             :                                                   METRICS_VOLTAGE_VDDSOC,
    1291             :                                                   (uint32_t *)data);
    1292           0 :                 *size = 4;
    1293           0 :                 break;
    1294             :         case AMDGPU_PP_SENSOR_GPU_POWER:
    1295           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1296             :                                                   METRICS_AVERAGE_SOCKETPOWER,
    1297             :                                                   (uint32_t *)data);
    1298           0 :                 *size = 4;
    1299           0 :                 break;
    1300             :         case AMDGPU_PP_SENSOR_SS_APU_SHARE:
    1301           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1302             :                                                   METRICS_SS_APU_SHARE,
    1303             :                                                   (uint32_t *)data);
    1304           0 :                 *size = 4;
    1305           0 :                 break;
    1306             :         case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
    1307           0 :                 ret = renoir_get_smu_metrics_data(smu,
    1308             :                                                   METRICS_SS_DGPU_SHARE,
    1309             :                                                   (uint32_t *)data);
    1310           0 :                 *size = 4;
    1311           0 :                 break;
    1312             :         default:
    1313             :                 ret = -EOPNOTSUPP;
    1314             :                 break;
    1315             :         }
    1316             : 
    1317             :         return ret;
    1318             : }
    1319             : 
    1320           0 : static bool renoir_is_dpm_running(struct smu_context *smu)
    1321             : {
    1322           0 :         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           0 :         if (adev->in_suspend)
    1330             :                 return false;
    1331             :         else
    1332           0 :                 return true;
    1333             : 
    1334             : }
    1335             : 
    1336           0 : static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
    1337             :                                       void **table)
    1338             : {
    1339           0 :         struct smu_table_context *smu_table = &smu->smu_table;
    1340           0 :         struct gpu_metrics_v2_2 *gpu_metrics =
    1341             :                 (struct gpu_metrics_v2_2 *)smu_table->gpu_metrics_table;
    1342             :         SmuMetrics_t metrics;
    1343           0 :         int ret = 0;
    1344             : 
    1345           0 :         ret = smu_cmn_get_metrics_table(smu, &metrics, true);
    1346           0 :         if (ret)
    1347           0 :                 return ret;
    1348             : 
    1349           0 :         smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 2);
    1350             : 
    1351           0 :         gpu_metrics->temperature_gfx = metrics.GfxTemperature;
    1352           0 :         gpu_metrics->temperature_soc = metrics.SocTemperature;
    1353           0 :         memcpy(&gpu_metrics->temperature_core[0],
    1354             :                 &metrics.CoreTemperature[0],
    1355             :                 sizeof(uint16_t) * 8);
    1356           0 :         gpu_metrics->temperature_l3[0] = metrics.L3Temperature[0];
    1357           0 :         gpu_metrics->temperature_l3[1] = metrics.L3Temperature[1];
    1358             : 
    1359           0 :         gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity;
    1360           0 :         gpu_metrics->average_mm_activity = metrics.AverageUvdActivity;
    1361             : 
    1362           0 :         gpu_metrics->average_socket_power = metrics.CurrentSocketPower;
    1363           0 :         gpu_metrics->average_cpu_power = metrics.Power[0];
    1364           0 :         gpu_metrics->average_soc_power = metrics.Power[1];
    1365           0 :         memcpy(&gpu_metrics->average_core_power[0],
    1366             :                 &metrics.CorePower[0],
    1367             :                 sizeof(uint16_t) * 8);
    1368             : 
    1369           0 :         gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency;
    1370           0 :         gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency;
    1371           0 :         gpu_metrics->average_fclk_frequency = metrics.AverageFclkFrequency;
    1372           0 :         gpu_metrics->average_vclk_frequency = metrics.AverageVclkFrequency;
    1373             : 
    1374           0 :         gpu_metrics->current_gfxclk = metrics.ClockFrequency[CLOCK_GFXCLK];
    1375           0 :         gpu_metrics->current_socclk = metrics.ClockFrequency[CLOCK_SOCCLK];
    1376           0 :         gpu_metrics->current_uclk = metrics.ClockFrequency[CLOCK_UMCCLK];
    1377           0 :         gpu_metrics->current_fclk = metrics.ClockFrequency[CLOCK_FCLK];
    1378           0 :         gpu_metrics->current_vclk = metrics.ClockFrequency[CLOCK_VCLK];
    1379           0 :         gpu_metrics->current_dclk = metrics.ClockFrequency[CLOCK_DCLK];
    1380           0 :         memcpy(&gpu_metrics->current_coreclk[0],
    1381             :                 &metrics.CoreFrequency[0],
    1382             :                 sizeof(uint16_t) * 8);
    1383           0 :         gpu_metrics->current_l3clk[0] = metrics.L3Frequency[0];
    1384           0 :         gpu_metrics->current_l3clk[1] = metrics.L3Frequency[1];
    1385             : 
    1386           0 :         gpu_metrics->throttle_status = metrics.ThrottlerStatus;
    1387           0 :         gpu_metrics->indep_throttle_status =
    1388           0 :                 smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
    1389             :                                                    renoir_throttler_map);
    1390             : 
    1391           0 :         gpu_metrics->fan_pwm = metrics.FanPwm;
    1392             : 
    1393           0 :         gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
    1394             : 
    1395           0 :         *table = (void *)gpu_metrics;
    1396             : 
    1397           0 :         return sizeof(struct gpu_metrics_v2_2);
    1398             : }
    1399             : 
    1400           0 : static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state)
    1401             : {
    1402             : 
    1403           0 :         return 0;
    1404             : }
    1405             : 
    1406           0 : static int renoir_get_enabled_mask(struct smu_context *smu,
    1407             :                                    uint64_t *feature_mask)
    1408             : {
    1409           0 :         if (!feature_mask)
    1410             :                 return -EINVAL;
    1411           0 :         memset(feature_mask, 0xff, sizeof(*feature_mask));
    1412             : 
    1413           0 :         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           0 : void renoir_set_ppt_funcs(struct smu_context *smu)
    1458             : {
    1459           0 :         struct amdgpu_device *adev = smu->adev;
    1460             : 
    1461           0 :         smu->ppt_funcs = &renoir_ppt_funcs;
    1462           0 :         smu->message_map = renoir_message_map;
    1463           0 :         smu->clock_map = renoir_clk_map;
    1464           0 :         smu->table_map = renoir_table_map;
    1465           0 :         smu->workload_map = renoir_workload_map;
    1466           0 :         smu->smc_driver_if_version = SMU12_DRIVER_IF_VERSION;
    1467           0 :         smu->is_apu = true;
    1468           0 :         smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82);
    1469           0 :         smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66);
    1470           0 :         smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
    1471           0 : }

Generated by: LCOV version 1.14