Merge tag 'devicetree-fixes-for-6.5-1' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / pm / swsmu / smu13 / smu_v13_0_7_ppt.c
1 /*
2  * Copyright 2021 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23
24 #define SWSMU_CODE_LAYER_L2
25
26 #include <linux/firmware.h>
27 #include <linux/pci.h>
28 #include <linux/i2c.h>
29 #include "amdgpu.h"
30 #include "amdgpu_smu.h"
31 #include "atomfirmware.h"
32 #include "amdgpu_atomfirmware.h"
33 #include "amdgpu_atombios.h"
34 #include "smu_v13_0.h"
35 #include "smu13_driver_if_v13_0_7.h"
36 #include "soc15_common.h"
37 #include "atom.h"
38 #include "smu_v13_0_7_ppt.h"
39 #include "smu_v13_0_7_pptable.h"
40 #include "smu_v13_0_7_ppsmc.h"
41 #include "nbio/nbio_4_3_0_offset.h"
42 #include "nbio/nbio_4_3_0_sh_mask.h"
43 #include "mp/mp_13_0_0_offset.h"
44 #include "mp/mp_13_0_0_sh_mask.h"
45
46 #include "asic_reg/mp/mp_13_0_0_sh_mask.h"
47 #include "smu_cmn.h"
48 #include "amdgpu_ras.h"
49
50 /*
51  * DO NOT use these for err/warn/info/debug messages.
52  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
53  * They are more MGPU friendly.
54  */
55 #undef pr_err
56 #undef pr_warn
57 #undef pr_info
58 #undef pr_debug
59
60 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
61
62 #define FEATURE_MASK(feature) (1ULL << feature)
63 #define SMC_DPM_FEATURE ( \
64         FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT)     | \
65         FEATURE_MASK(FEATURE_DPM_UCLK_BIT)       | \
66         FEATURE_MASK(FEATURE_DPM_LINK_BIT)       | \
67         FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT)     | \
68         FEATURE_MASK(FEATURE_DPM_FCLK_BIT)       | \
69         FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT))
70
71 #define smnMP1_FIRMWARE_FLAGS_SMU_13_0_7   0x3b10028
72
73 #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE   0x4000
74
75 static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] = {
76         MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage,                 1),
77         MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetSmuVersion,               1),
78         MSG_MAP(GetDriverIfVersion,             PPSMC_MSG_GetDriverIfVersion,          1),
79         MSG_MAP(SetAllowedFeaturesMaskLow,      PPSMC_MSG_SetAllowedFeaturesMaskLow,   0),
80         MSG_MAP(SetAllowedFeaturesMaskHigh,     PPSMC_MSG_SetAllowedFeaturesMaskHigh,  0),
81         MSG_MAP(EnableAllSmuFeatures,           PPSMC_MSG_EnableAllSmuFeatures,        0),
82         MSG_MAP(DisableAllSmuFeatures,          PPSMC_MSG_DisableAllSmuFeatures,       0),
83         MSG_MAP(EnableSmuFeaturesLow,           PPSMC_MSG_EnableSmuFeaturesLow,        1),
84         MSG_MAP(EnableSmuFeaturesHigh,          PPSMC_MSG_EnableSmuFeaturesHigh,       1),
85         MSG_MAP(DisableSmuFeaturesLow,          PPSMC_MSG_DisableSmuFeaturesLow,       1),
86         MSG_MAP(DisableSmuFeaturesHigh,         PPSMC_MSG_DisableSmuFeaturesHigh,      1),
87         MSG_MAP(GetEnabledSmuFeaturesLow,       PPSMC_MSG_GetRunningSmuFeaturesLow,    1),
88         MSG_MAP(GetEnabledSmuFeaturesHigh,      PPSMC_MSG_GetRunningSmuFeaturesHigh,   1),
89         MSG_MAP(SetWorkloadMask,                PPSMC_MSG_SetWorkloadMask,             1),
90         MSG_MAP(SetPptLimit,                    PPSMC_MSG_SetPptLimit,                 0),
91         MSG_MAP(SetDriverDramAddrHigh,          PPSMC_MSG_SetDriverDramAddrHigh,       1),
92         MSG_MAP(SetDriverDramAddrLow,           PPSMC_MSG_SetDriverDramAddrLow,        1),
93         MSG_MAP(SetToolsDramAddrHigh,           PPSMC_MSG_SetToolsDramAddrHigh,        0),
94         MSG_MAP(SetToolsDramAddrLow,            PPSMC_MSG_SetToolsDramAddrLow,         0),
95         MSG_MAP(TransferTableSmu2Dram,          PPSMC_MSG_TransferTableSmu2Dram,       1),
96         MSG_MAP(TransferTableDram2Smu,          PPSMC_MSG_TransferTableDram2Smu,       0),
97         MSG_MAP(UseDefaultPPTable,              PPSMC_MSG_UseDefaultPPTable,           0),
98         MSG_MAP(RunDcBtc,                       PPSMC_MSG_RunDcBtc,                    0),
99         MSG_MAP(EnterBaco,                      PPSMC_MSG_EnterBaco,                   0),
100         MSG_MAP(ExitBaco,           PPSMC_MSG_ExitBaco,                            0),
101         MSG_MAP(SetSoftMinByFreq,               PPSMC_MSG_SetSoftMinByFreq,            1),
102         MSG_MAP(SetSoftMaxByFreq,               PPSMC_MSG_SetSoftMaxByFreq,            1),
103         MSG_MAP(SetHardMinByFreq,               PPSMC_MSG_SetHardMinByFreq,            1),
104         MSG_MAP(SetHardMaxByFreq,               PPSMC_MSG_SetHardMaxByFreq,            0),
105         MSG_MAP(GetMinDpmFreq,                  PPSMC_MSG_GetMinDpmFreq,               1),
106         MSG_MAP(GetMaxDpmFreq,                  PPSMC_MSG_GetMaxDpmFreq,               1),
107         MSG_MAP(GetDpmFreqByIndex,              PPSMC_MSG_GetDpmFreqByIndex,           1),
108         MSG_MAP(PowerUpVcn,                             PPSMC_MSG_PowerUpVcn,                  0),
109         MSG_MAP(PowerDownVcn,                   PPSMC_MSG_PowerDownVcn,                0),
110         MSG_MAP(PowerUpJpeg,                    PPSMC_MSG_PowerUpJpeg,                 0),
111         MSG_MAP(PowerDownJpeg,                  PPSMC_MSG_PowerDownJpeg,               0),
112         MSG_MAP(GetDcModeMaxDpmFreq,            PPSMC_MSG_GetDcModeMaxDpmFreq,         1),
113         MSG_MAP(OverridePcieParameters,         PPSMC_MSG_OverridePcieParameters,      0),
114         MSG_MAP(ReenableAcDcInterrupt,          PPSMC_MSG_ReenableAcDcInterrupt,       0),
115         MSG_MAP(AllowIHHostInterrupt,           PPSMC_MSG_AllowIHHostInterrupt,       0),
116         MSG_MAP(DramLogSetDramAddrHigh,         PPSMC_MSG_DramLogSetDramAddrHigh,      0),
117         MSG_MAP(DramLogSetDramAddrLow,          PPSMC_MSG_DramLogSetDramAddrLow,       0),
118         MSG_MAP(DramLogSetDramSize,             PPSMC_MSG_DramLogSetDramSize,          0),
119         MSG_MAP(AllowGfxOff,                    PPSMC_MSG_AllowGfxOff,                 0),
120         MSG_MAP(DisallowGfxOff,                 PPSMC_MSG_DisallowGfxOff,              0),
121         MSG_MAP(Mode1Reset,             PPSMC_MSG_Mode1Reset,                  0),
122         MSG_MAP(PrepareMp1ForUnload,            PPSMC_MSG_PrepareMp1ForUnload,         0),
123         MSG_MAP(SetMGpuFanBoostLimitRpm,        PPSMC_MSG_SetMGpuFanBoostLimitRpm,     0),
124         MSG_MAP(DFCstateControl,                PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
125         MSG_MAP(ArmD3,                          PPSMC_MSG_ArmD3,                       0),
126         MSG_MAP(AllowGpo,                       PPSMC_MSG_SetGpoAllow,           0),
127         MSG_MAP(GetPptLimit,                    PPSMC_MSG_GetPptLimit,                 0),
128         MSG_MAP(NotifyPowerSource,              PPSMC_MSG_NotifyPowerSource,           0),
129 };
130
131 static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = {
132         CLK_MAP(GFXCLK,         PPCLK_GFXCLK),
133         CLK_MAP(SCLK,           PPCLK_GFXCLK),
134         CLK_MAP(SOCCLK,         PPCLK_SOCCLK),
135         CLK_MAP(FCLK,           PPCLK_FCLK),
136         CLK_MAP(UCLK,           PPCLK_UCLK),
137         CLK_MAP(MCLK,           PPCLK_UCLK),
138         CLK_MAP(VCLK,           PPCLK_VCLK_0),
139         CLK_MAP(VCLK1,          PPCLK_VCLK_1),
140         CLK_MAP(DCLK,           PPCLK_DCLK_0),
141         CLK_MAP(DCLK1,          PPCLK_DCLK_1),
142 };
143
144 static struct cmn2asic_mapping smu_v13_0_7_feature_mask_map[SMU_FEATURE_COUNT] = {
145         FEA_MAP(FW_DATA_READ),
146         FEA_MAP(DPM_GFXCLK),
147         FEA_MAP(DPM_GFX_POWER_OPTIMIZER),
148         FEA_MAP(DPM_UCLK),
149         FEA_MAP(DPM_FCLK),
150         FEA_MAP(DPM_SOCCLK),
151         FEA_MAP(DPM_MP0CLK),
152         FEA_MAP(DPM_LINK),
153         FEA_MAP(DPM_DCN),
154         FEA_MAP(VMEMP_SCALING),
155         FEA_MAP(VDDIO_MEM_SCALING),
156         FEA_MAP(DS_GFXCLK),
157         FEA_MAP(DS_SOCCLK),
158         FEA_MAP(DS_FCLK),
159         FEA_MAP(DS_LCLK),
160         FEA_MAP(DS_DCFCLK),
161         FEA_MAP(DS_UCLK),
162         FEA_MAP(GFX_ULV),
163         FEA_MAP(FW_DSTATE),
164         FEA_MAP(GFXOFF),
165         FEA_MAP(BACO),
166         FEA_MAP(MM_DPM),
167         FEA_MAP(SOC_MPCLK_DS),
168         FEA_MAP(BACO_MPCLK_DS),
169         FEA_MAP(THROTTLERS),
170         FEA_MAP(SMARTSHIFT),
171         FEA_MAP(GTHR),
172         FEA_MAP(ACDC),
173         FEA_MAP(VR0HOT),
174         FEA_MAP(FW_CTF),
175         FEA_MAP(FAN_CONTROL),
176         FEA_MAP(GFX_DCS),
177         FEA_MAP(GFX_READ_MARGIN),
178         FEA_MAP(LED_DISPLAY),
179         FEA_MAP(GFXCLK_SPREAD_SPECTRUM),
180         FEA_MAP(OUT_OF_BAND_MONITOR),
181         FEA_MAP(OPTIMIZED_VMIN),
182         FEA_MAP(GFX_IMU),
183         FEA_MAP(BOOT_TIME_CAL),
184         FEA_MAP(GFX_PCC_DFLL),
185         FEA_MAP(SOC_CG),
186         FEA_MAP(DF_CSTATE),
187         FEA_MAP(GFX_EDC),
188         FEA_MAP(BOOT_POWER_OPT),
189         FEA_MAP(CLOCK_POWER_DOWN_BYPASS),
190         FEA_MAP(DS_VCN),
191         FEA_MAP(BACO_CG),
192         FEA_MAP(MEM_TEMP_READ),
193         FEA_MAP(ATHUB_MMHUB_PG),
194         FEA_MAP(SOC_PCC),
195         [SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
196         [SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
197         [SMU_FEATURE_PPT_BIT] = {1, FEATURE_THROTTLERS_BIT},
198 };
199
200 static struct cmn2asic_mapping smu_v13_0_7_table_map[SMU_TABLE_COUNT] = {
201         TAB_MAP(PPTABLE),
202         TAB_MAP(WATERMARKS),
203         TAB_MAP(AVFS_PSM_DEBUG),
204         TAB_MAP(PMSTATUSLOG),
205         TAB_MAP(SMU_METRICS),
206         TAB_MAP(DRIVER_SMU_CONFIG),
207         TAB_MAP(ACTIVITY_MONITOR_COEFF),
208         [SMU_TABLE_COMBO_PPTABLE] = {1, TABLE_COMBO_PPTABLE},
209         TAB_MAP(OVERDRIVE),
210 };
211
212 static struct cmn2asic_mapping smu_v13_0_7_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
213         PWR_MAP(AC),
214         PWR_MAP(DC),
215 };
216
217 static struct cmn2asic_mapping smu_v13_0_7_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
218         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT,       WORKLOAD_PPLIB_DEFAULT_BIT),
219         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D,         WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
220         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING,          WORKLOAD_PPLIB_POWER_SAVING_BIT),
221         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,                WORKLOAD_PPLIB_VIDEO_BIT),
222         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR,                   WORKLOAD_PPLIB_VR_BIT),
223         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,              WORKLOAD_PPLIB_COMPUTE_BIT),
224         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,               WORKLOAD_PPLIB_CUSTOM_BIT),
225         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_WINDOW3D,             WORKLOAD_PPLIB_WINDOW_3D_BIT),
226 };
227
228 static const uint8_t smu_v13_0_7_throttler_map[] = {
229         [THROTTLER_PPT0_BIT]            = (SMU_THROTTLER_PPT0_BIT),
230         [THROTTLER_PPT1_BIT]            = (SMU_THROTTLER_PPT1_BIT),
231         [THROTTLER_PPT2_BIT]            = (SMU_THROTTLER_PPT2_BIT),
232         [THROTTLER_PPT3_BIT]            = (SMU_THROTTLER_PPT3_BIT),
233         [THROTTLER_TDC_GFX_BIT]         = (SMU_THROTTLER_TDC_GFX_BIT),
234         [THROTTLER_TDC_SOC_BIT]         = (SMU_THROTTLER_TDC_SOC_BIT),
235         [THROTTLER_TEMP_EDGE_BIT]       = (SMU_THROTTLER_TEMP_EDGE_BIT),
236         [THROTTLER_TEMP_HOTSPOT_BIT]    = (SMU_THROTTLER_TEMP_HOTSPOT_BIT),
237         [THROTTLER_TEMP_MEM_BIT]        = (SMU_THROTTLER_TEMP_MEM_BIT),
238         [THROTTLER_TEMP_VR_GFX_BIT]     = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
239         [THROTTLER_TEMP_VR_SOC_BIT]     = (SMU_THROTTLER_TEMP_VR_SOC_BIT),
240         [THROTTLER_TEMP_VR_MEM0_BIT]    = (SMU_THROTTLER_TEMP_VR_MEM0_BIT),
241         [THROTTLER_TEMP_VR_MEM1_BIT]    = (SMU_THROTTLER_TEMP_VR_MEM1_BIT),
242         [THROTTLER_TEMP_LIQUID0_BIT]    = (SMU_THROTTLER_TEMP_LIQUID0_BIT),
243         [THROTTLER_TEMP_LIQUID1_BIT]    = (SMU_THROTTLER_TEMP_LIQUID1_BIT),
244         [THROTTLER_GFX_APCC_PLUS_BIT]   = (SMU_THROTTLER_APCC_BIT),
245         [THROTTLER_FIT_BIT]             = (SMU_THROTTLER_FIT_BIT),
246 };
247
248 static int
249 smu_v13_0_7_get_allowed_feature_mask(struct smu_context *smu,
250                                   uint32_t *feature_mask, uint32_t num)
251 {
252         struct amdgpu_device *adev = smu->adev;
253
254         if (num > 2)
255                 return -EINVAL;
256
257         memset(feature_mask, 0, sizeof(uint32_t) * num);
258
259         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_FW_DATA_READ_BIT);
260
261         if (adev->pm.pp_feature & PP_SCLK_DPM_MASK) {
262                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT);
263                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_IMU_BIT);
264                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFX_POWER_OPTIMIZER_BIT);
265         }
266
267         if (adev->pm.pp_feature & PP_GFXOFF_MASK)
268                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXOFF_BIT);
269
270         if (adev->pm.pp_feature & PP_MCLK_DPM_MASK) {
271                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT);
272                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_FCLK_BIT);
273                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_VMEMP_SCALING_BIT);
274                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_VDDIO_MEM_SCALING_BIT);
275         }
276
277         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT);
278
279         if (adev->pm.pp_feature & PP_PCIE_DPM_MASK)
280                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_LINK_BIT);
281
282         if (adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK)
283                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_GFXCLK_BIT);
284
285         if (adev->pm.pp_feature & PP_ULV_MASK)
286                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_ULV_BIT);
287
288         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_LCLK_BIT);
289         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT);
290         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MM_DPM_BIT);
291         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_VCN_BIT);
292         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_FCLK_BIT);
293         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DF_CSTATE_BIT);
294         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_THROTTLERS_BIT);
295         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_VR0HOT_BIT);
296         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_FW_CTF_BIT);
297         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_FAN_CONTROL_BIT);
298         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_SOCCLK_BIT);
299         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXCLK_SPREAD_SPECTRUM_BIT);
300         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MEM_TEMP_READ_BIT);
301         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_FW_DSTATE_BIT);
302         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_SOC_MPCLK_DS_BIT);
303         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_BACO_MPCLK_DS_BIT);
304         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_PCC_DFLL_BIT);
305         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_SOC_CG_BIT);
306         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_BACO_BIT);
307
308         if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK)
309                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_DCN_BIT);
310
311         if ((adev->pg_flags & AMD_PG_SUPPORT_ATHUB) &&
312             (adev->pg_flags & AMD_PG_SUPPORT_MMHUB))
313                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ATHUB_MMHUB_PG_BIT);
314
315         return 0;
316 }
317
318 static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu)
319 {
320         struct smu_table_context *table_context = &smu->smu_table;
321         struct smu_13_0_7_powerplay_table *powerplay_table =
322                 table_context->power_play_table;
323         struct smu_baco_context *smu_baco = &smu->smu_baco;
324         PPTable_t *smc_pptable = table_context->driver_pptable;
325         BoardTable_t *BoardTable = &smc_pptable->BoardTable;
326         const OverDriveLimits_t * const overdrive_upperlimits =
327                                 &smc_pptable->SkuTable.OverDriveLimitsBasicMax;
328         const OverDriveLimits_t * const overdrive_lowerlimits =
329                                 &smc_pptable->SkuTable.OverDriveLimitsMin;
330
331         if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_HARDWAREDC)
332                 smu->dc_controlled_by_gpio = true;
333
334         if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_BACO ||
335             powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_MACO)
336                 smu_baco->platform_support = true;
337
338         if (smu_baco->platform_support && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled))
339                 smu_baco->maco_support = true;
340
341         if (!overdrive_lowerlimits->FeatureCtrlMask ||
342             !overdrive_upperlimits->FeatureCtrlMask)
343                 smu->od_enabled = false;
344
345         table_context->thermal_controller_type =
346                 powerplay_table->thermal_controller_type;
347
348         /*
349          * Instead of having its own buffer space and get overdrive_table copied,
350          * smu->od_settings just points to the actual overdrive_table
351          */
352         smu->od_settings = &powerplay_table->overdrive_table;
353
354         return 0;
355 }
356
357 static int smu_v13_0_7_store_powerplay_table(struct smu_context *smu)
358 {
359         struct smu_table_context *table_context = &smu->smu_table;
360         struct smu_13_0_7_powerplay_table *powerplay_table =
361                 table_context->power_play_table;
362         struct amdgpu_device *adev = smu->adev;
363
364         if (adev->pdev->device == 0x51)
365                 powerplay_table->smc_pptable.SkuTable.DebugOverrides |= 0x00000080;
366
367         memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
368                sizeof(PPTable_t));
369
370         return 0;
371 }
372
373 static int smu_v13_0_7_check_fw_status(struct smu_context *smu)
374 {
375         struct amdgpu_device *adev = smu->adev;
376         uint32_t mp1_fw_flags;
377
378         mp1_fw_flags = RREG32_PCIE(MP1_Public |
379                                    (smnMP1_FIRMWARE_FLAGS_SMU_13_0_7 & 0xffffffff));
380
381         if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
382                         MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
383                 return 0;
384
385         return -EIO;
386 }
387
388 #ifndef atom_smc_dpm_info_table_13_0_7
389 struct atom_smc_dpm_info_table_13_0_7
390 {
391         struct atom_common_table_header table_header;
392         BoardTable_t BoardTable;
393 };
394 #endif
395
396 static int smu_v13_0_7_append_powerplay_table(struct smu_context *smu)
397 {
398         struct smu_table_context *table_context = &smu->smu_table;
399
400         PPTable_t *smc_pptable = table_context->driver_pptable;
401
402         struct atom_smc_dpm_info_table_13_0_7 *smc_dpm_table;
403
404         BoardTable_t *BoardTable = &smc_pptable->BoardTable;
405
406         int index, ret;
407
408         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
409         smc_dpm_info);
410
411         ret = amdgpu_atombios_get_data_table(smu->adev, index, NULL, NULL, NULL,
412                         (uint8_t **)&smc_dpm_table);
413         if (ret)
414                 return ret;
415
416         memcpy(BoardTable, &smc_dpm_table->BoardTable, sizeof(BoardTable_t));
417
418         return 0;
419 }
420
421 static int smu_v13_0_7_get_pptable_from_pmfw(struct smu_context *smu,
422                                              void **table,
423                                              uint32_t *size)
424 {
425         struct smu_table_context *smu_table = &smu->smu_table;
426         void *combo_pptable = smu_table->combo_pptable;
427         int ret = 0;
428
429         ret = smu_cmn_get_combo_pptable(smu);
430         if (ret)
431                 return ret;
432
433         *table = combo_pptable;
434         *size = sizeof(struct smu_13_0_7_powerplay_table);
435
436         return 0;
437 }
438
439 static int smu_v13_0_7_setup_pptable(struct smu_context *smu)
440 {
441         struct smu_table_context *smu_table = &smu->smu_table;
442         struct amdgpu_device *adev = smu->adev;
443         int ret = 0;
444
445         /*
446          * With SCPM enabled, the pptable used will be signed. It cannot
447          * be used directly by driver. To get the raw pptable, we need to
448          * rely on the combo pptable(and its revelant SMU message).
449          */
450         ret = smu_v13_0_7_get_pptable_from_pmfw(smu,
451                                                 &smu_table->power_play_table,
452                                                 &smu_table->power_play_table_size);
453         if (ret)
454                 return ret;
455
456         ret = smu_v13_0_7_store_powerplay_table(smu);
457         if (ret)
458                 return ret;
459
460         /*
461          * With SCPM enabled, the operation below will be handled
462          * by PSP. Driver involvment is unnecessary and useless.
463          */
464         if (!adev->scpm_enabled) {
465                 ret = smu_v13_0_7_append_powerplay_table(smu);
466                 if (ret)
467                         return ret;
468         }
469
470         ret = smu_v13_0_7_check_powerplay_table(smu);
471         if (ret)
472                 return ret;
473
474         return ret;
475 }
476
477 static int smu_v13_0_7_tables_init(struct smu_context *smu)
478 {
479         struct smu_table_context *smu_table = &smu->smu_table;
480         struct smu_table *tables = smu_table->tables;
481
482         SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
483                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
484
485         SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
486                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
487         SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetricsExternal_t),
488                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
489         SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
490                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
491         SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTableExternal_t),
492                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
493         SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU13_TOOL_SIZE,
494                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
495         SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF,
496                        sizeof(DpmActivityMonitorCoeffIntExternal_t), PAGE_SIZE,
497                        AMDGPU_GEM_DOMAIN_VRAM);
498         SMU_TABLE_INIT(tables, SMU_TABLE_COMBO_PPTABLE, MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE,
499                         PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
500
501         smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), GFP_KERNEL);
502         if (!smu_table->metrics_table)
503                 goto err0_out;
504         smu_table->metrics_time = 0;
505
506         smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_3);
507         smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
508         if (!smu_table->gpu_metrics_table)
509                 goto err1_out;
510
511         smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
512         if (!smu_table->watermarks_table)
513                 goto err2_out;
514
515         return 0;
516
517 err2_out:
518         kfree(smu_table->gpu_metrics_table);
519 err1_out:
520         kfree(smu_table->metrics_table);
521 err0_out:
522         return -ENOMEM;
523 }
524
525 static int smu_v13_0_7_allocate_dpm_context(struct smu_context *smu)
526 {
527         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
528
529         smu_dpm->dpm_context = kzalloc(sizeof(struct smu_13_0_dpm_context),
530                                        GFP_KERNEL);
531         if (!smu_dpm->dpm_context)
532                 return -ENOMEM;
533
534         smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context);
535
536         return 0;
537 }
538
539 static int smu_v13_0_7_init_smc_tables(struct smu_context *smu)
540 {
541         int ret = 0;
542
543         ret = smu_v13_0_7_tables_init(smu);
544         if (ret)
545                 return ret;
546
547         ret = smu_v13_0_7_allocate_dpm_context(smu);
548         if (ret)
549                 return ret;
550
551         return smu_v13_0_init_smc_tables(smu);
552 }
553
554 static int smu_v13_0_7_set_default_dpm_table(struct smu_context *smu)
555 {
556         struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
557         PPTable_t *driver_ppt = smu->smu_table.driver_pptable;
558         SkuTable_t *skutable = &driver_ppt->SkuTable;
559         struct smu_13_0_dpm_table *dpm_table;
560         struct smu_13_0_pcie_table *pcie_table;
561         uint32_t link_level;
562         int ret = 0;
563
564         /* socclk dpm table setup */
565         dpm_table = &dpm_context->dpm_tables.soc_table;
566         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
567                 ret = smu_v13_0_set_single_dpm_table(smu,
568                                                      SMU_SOCCLK,
569                                                      dpm_table);
570                 if (ret)
571                         return ret;
572         } else {
573                 dpm_table->count = 1;
574                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
575                 dpm_table->dpm_levels[0].enabled = true;
576                 dpm_table->min = dpm_table->dpm_levels[0].value;
577                 dpm_table->max = dpm_table->dpm_levels[0].value;
578         }
579
580         /* gfxclk dpm table setup */
581         dpm_table = &dpm_context->dpm_tables.gfx_table;
582         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
583                 ret = smu_v13_0_set_single_dpm_table(smu,
584                                                      SMU_GFXCLK,
585                                                      dpm_table);
586                 if (ret)
587                         return ret;
588
589                 if (skutable->DriverReportedClocks.GameClockAc &&
590                         (dpm_table->dpm_levels[dpm_table->count - 1].value >
591                         skutable->DriverReportedClocks.GameClockAc)) {
592                         dpm_table->dpm_levels[dpm_table->count - 1].value =
593                                 skutable->DriverReportedClocks.GameClockAc;
594                         dpm_table->max = skutable->DriverReportedClocks.GameClockAc;
595                 }
596         } else {
597                 dpm_table->count = 1;
598                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
599                 dpm_table->dpm_levels[0].enabled = true;
600                 dpm_table->min = dpm_table->dpm_levels[0].value;
601                 dpm_table->max = dpm_table->dpm_levels[0].value;
602         }
603
604         /* uclk dpm table setup */
605         dpm_table = &dpm_context->dpm_tables.uclk_table;
606         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
607                 ret = smu_v13_0_set_single_dpm_table(smu,
608                                                      SMU_UCLK,
609                                                      dpm_table);
610                 if (ret)
611                         return ret;
612         } else {
613                 dpm_table->count = 1;
614                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
615                 dpm_table->dpm_levels[0].enabled = true;
616                 dpm_table->min = dpm_table->dpm_levels[0].value;
617                 dpm_table->max = dpm_table->dpm_levels[0].value;
618         }
619
620         /* fclk dpm table setup */
621         dpm_table = &dpm_context->dpm_tables.fclk_table;
622         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
623                 ret = smu_v13_0_set_single_dpm_table(smu,
624                                                      SMU_FCLK,
625                                                      dpm_table);
626                 if (ret)
627                         return ret;
628         } else {
629                 dpm_table->count = 1;
630                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.fclk / 100;
631                 dpm_table->dpm_levels[0].enabled = true;
632                 dpm_table->min = dpm_table->dpm_levels[0].value;
633                 dpm_table->max = dpm_table->dpm_levels[0].value;
634         }
635
636         /* vclk dpm table setup */
637         dpm_table = &dpm_context->dpm_tables.vclk_table;
638         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_VCLK_BIT)) {
639                 ret = smu_v13_0_set_single_dpm_table(smu,
640                                                      SMU_VCLK,
641                                                      dpm_table);
642                 if (ret)
643                         return ret;
644         } else {
645                 dpm_table->count = 1;
646                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100;
647                 dpm_table->dpm_levels[0].enabled = true;
648                 dpm_table->min = dpm_table->dpm_levels[0].value;
649                 dpm_table->max = dpm_table->dpm_levels[0].value;
650         }
651
652         /* dclk dpm table setup */
653         dpm_table = &dpm_context->dpm_tables.dclk_table;
654         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCLK_BIT)) {
655                 ret = smu_v13_0_set_single_dpm_table(smu,
656                                                      SMU_DCLK,
657                                                      dpm_table);
658                 if (ret)
659                         return ret;
660         } else {
661                 dpm_table->count = 1;
662                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100;
663                 dpm_table->dpm_levels[0].enabled = true;
664                 dpm_table->min = dpm_table->dpm_levels[0].value;
665                 dpm_table->max = dpm_table->dpm_levels[0].value;
666         }
667
668         /* lclk dpm table setup */
669         pcie_table = &dpm_context->dpm_tables.pcie_table;
670         pcie_table->num_of_link_levels = 0;
671         for (link_level = 0; link_level < NUM_LINK_LEVELS; link_level++) {
672                 if (!skutable->PcieGenSpeed[link_level] &&
673                     !skutable->PcieLaneCount[link_level] &&
674                     !skutable->LclkFreq[link_level])
675                         continue;
676
677                 pcie_table->pcie_gen[pcie_table->num_of_link_levels] =
678                                         skutable->PcieGenSpeed[link_level];
679                 pcie_table->pcie_lane[pcie_table->num_of_link_levels] =
680                                         skutable->PcieLaneCount[link_level];
681                 pcie_table->clk_freq[pcie_table->num_of_link_levels] =
682                                         skutable->LclkFreq[link_level];
683                 pcie_table->num_of_link_levels++;
684         }
685
686         return 0;
687 }
688
689 static bool smu_v13_0_7_is_dpm_running(struct smu_context *smu)
690 {
691         int ret = 0;
692         uint64_t feature_enabled;
693
694         ret = smu_cmn_get_enabled_mask(smu, &feature_enabled);
695         if (ret)
696                 return false;
697
698         return !!(feature_enabled & SMC_DPM_FEATURE);
699 }
700
701 static void smu_v13_0_7_dump_pptable(struct smu_context *smu)
702 {
703        struct smu_table_context *table_context = &smu->smu_table;
704        PPTable_t *pptable = table_context->driver_pptable;
705        SkuTable_t *skutable = &pptable->SkuTable;
706
707        dev_info(smu->adev->dev, "Dumped PPTable:\n");
708
709        dev_info(smu->adev->dev, "Version = 0x%08x\n", skutable->Version);
710        dev_info(smu->adev->dev, "FeaturesToRun[0] = 0x%08x\n", skutable->FeaturesToRun[0]);
711        dev_info(smu->adev->dev, "FeaturesToRun[1] = 0x%08x\n", skutable->FeaturesToRun[1]);
712 }
713
714 static uint32_t smu_v13_0_7_get_throttler_status(SmuMetrics_t *metrics)
715 {
716         uint32_t throttler_status = 0;
717         int i;
718
719         for (i = 0; i < THROTTLER_COUNT; i++)
720                 throttler_status |=
721                         (metrics->ThrottlingPercentage[i] ? 1U << i : 0);
722
723         return throttler_status;
724 }
725
726 #define SMU_13_0_7_BUSY_THRESHOLD       15
727 static int smu_v13_0_7_get_smu_metrics_data(struct smu_context *smu,
728                                             MetricsMember_t member,
729                                             uint32_t *value)
730 {
731         struct smu_table_context *smu_table= &smu->smu_table;
732         SmuMetrics_t *metrics =
733                 &(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics);
734         int ret = 0;
735
736         ret = smu_cmn_get_metrics_table(smu,
737                                         NULL,
738                                         false);
739         if (ret)
740                 return ret;
741
742         switch (member) {
743         case METRICS_CURR_GFXCLK:
744                 *value = metrics->CurrClock[PPCLK_GFXCLK];
745                 break;
746         case METRICS_CURR_SOCCLK:
747                 *value = metrics->CurrClock[PPCLK_SOCCLK];
748                 break;
749         case METRICS_CURR_UCLK:
750                 *value = metrics->CurrClock[PPCLK_UCLK];
751                 break;
752         case METRICS_CURR_VCLK:
753                 *value = metrics->CurrClock[PPCLK_VCLK_0];
754                 break;
755         case METRICS_CURR_VCLK1:
756                 *value = metrics->CurrClock[PPCLK_VCLK_1];
757                 break;
758         case METRICS_CURR_DCLK:
759                 *value = metrics->CurrClock[PPCLK_DCLK_0];
760                 break;
761         case METRICS_CURR_DCLK1:
762                 *value = metrics->CurrClock[PPCLK_DCLK_1];
763                 break;
764         case METRICS_CURR_FCLK:
765                 *value = metrics->CurrClock[PPCLK_FCLK];
766                 break;
767         case METRICS_AVERAGE_GFXCLK:
768                 *value = metrics->AverageGfxclkFrequencyPreDs;
769                 break;
770         case METRICS_AVERAGE_FCLK:
771                 if (metrics->AverageUclkActivity <= SMU_13_0_7_BUSY_THRESHOLD)
772                         *value = metrics->AverageFclkFrequencyPostDs;
773                 else
774                         *value = metrics->AverageFclkFrequencyPreDs;
775                 break;
776         case METRICS_AVERAGE_UCLK:
777                 if (metrics->AverageUclkActivity <= SMU_13_0_7_BUSY_THRESHOLD)
778                         *value = metrics->AverageMemclkFrequencyPostDs;
779                 else
780                         *value = metrics->AverageMemclkFrequencyPreDs;
781                 break;
782         case METRICS_AVERAGE_VCLK:
783                 *value = metrics->AverageVclk0Frequency;
784                 break;
785         case METRICS_AVERAGE_DCLK:
786                 *value = metrics->AverageDclk0Frequency;
787                 break;
788         case METRICS_AVERAGE_VCLK1:
789                 *value = metrics->AverageVclk1Frequency;
790                 break;
791         case METRICS_AVERAGE_DCLK1:
792                 *value = metrics->AverageDclk1Frequency;
793                 break;
794         case METRICS_AVERAGE_GFXACTIVITY:
795                 *value = metrics->AverageGfxActivity;
796                 break;
797         case METRICS_AVERAGE_MEMACTIVITY:
798                 *value = metrics->AverageUclkActivity;
799                 break;
800         case METRICS_AVERAGE_SOCKETPOWER:
801                 *value = metrics->AverageSocketPower << 8;
802                 break;
803         case METRICS_TEMPERATURE_EDGE:
804                 *value = metrics->AvgTemperature[TEMP_EDGE] *
805                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
806                 break;
807         case METRICS_TEMPERATURE_HOTSPOT:
808                 *value = metrics->AvgTemperature[TEMP_HOTSPOT] *
809                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
810                 break;
811         case METRICS_TEMPERATURE_MEM:
812                 *value = metrics->AvgTemperature[TEMP_MEM] *
813                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
814                 break;
815         case METRICS_TEMPERATURE_VRGFX:
816                 *value = metrics->AvgTemperature[TEMP_VR_GFX] *
817                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
818                 break;
819         case METRICS_TEMPERATURE_VRSOC:
820                 *value = metrics->AvgTemperature[TEMP_VR_SOC] *
821                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
822                 break;
823         case METRICS_THROTTLER_STATUS:
824                 *value = smu_v13_0_7_get_throttler_status(metrics);
825                 break;
826         case METRICS_CURR_FANSPEED:
827                 *value = metrics->AvgFanRpm;
828                 break;
829         case METRICS_CURR_FANPWM:
830                 *value = metrics->AvgFanPwm;
831                 break;
832         case METRICS_VOLTAGE_VDDGFX:
833                 *value = metrics->AvgVoltage[SVI_PLANE_GFX];
834                 break;
835         case METRICS_PCIE_RATE:
836                 *value = metrics->PcieRate;
837                 break;
838         case METRICS_PCIE_WIDTH:
839                 *value = metrics->PcieWidth;
840                 break;
841         default:
842                 *value = UINT_MAX;
843                 break;
844         }
845
846         return ret;
847 }
848
849 static int smu_v13_0_7_get_dpm_ultimate_freq(struct smu_context *smu,
850                                              enum smu_clk_type clk_type,
851                                              uint32_t *min,
852                                              uint32_t *max)
853 {
854         struct smu_13_0_dpm_context *dpm_context =
855                 smu->smu_dpm.dpm_context;
856         struct smu_13_0_dpm_table *dpm_table;
857
858         switch (clk_type) {
859         case SMU_MCLK:
860         case SMU_UCLK:
861                 /* uclk dpm table */
862                 dpm_table = &dpm_context->dpm_tables.uclk_table;
863                 break;
864         case SMU_GFXCLK:
865         case SMU_SCLK:
866                 /* gfxclk dpm table */
867                 dpm_table = &dpm_context->dpm_tables.gfx_table;
868                 break;
869         case SMU_SOCCLK:
870                 /* socclk dpm table */
871                 dpm_table = &dpm_context->dpm_tables.soc_table;
872                 break;
873         case SMU_FCLK:
874                 /* fclk dpm table */
875                 dpm_table = &dpm_context->dpm_tables.fclk_table;
876                 break;
877         case SMU_VCLK:
878         case SMU_VCLK1:
879                 /* vclk dpm table */
880                 dpm_table = &dpm_context->dpm_tables.vclk_table;
881                 break;
882         case SMU_DCLK:
883         case SMU_DCLK1:
884                 /* dclk dpm table */
885                 dpm_table = &dpm_context->dpm_tables.dclk_table;
886                 break;
887         default:
888                 dev_err(smu->adev->dev, "Unsupported clock type!\n");
889                 return -EINVAL;
890         }
891
892         if (min)
893                 *min = dpm_table->min;
894         if (max)
895                 *max = dpm_table->max;
896
897         return 0;
898 }
899
900 static int smu_v13_0_7_read_sensor(struct smu_context *smu,
901                                    enum amd_pp_sensors sensor,
902                                    void *data,
903                                    uint32_t *size)
904 {
905         struct smu_table_context *table_context = &smu->smu_table;
906         PPTable_t *smc_pptable = table_context->driver_pptable;
907         int ret = 0;
908
909         switch (sensor) {
910         case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
911                 *(uint16_t *)data = smc_pptable->SkuTable.FanMaximumRpm;
912                 *size = 4;
913                 break;
914         case AMDGPU_PP_SENSOR_MEM_LOAD:
915                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
916                                                        METRICS_AVERAGE_MEMACTIVITY,
917                                                        (uint32_t *)data);
918                 *size = 4;
919                 break;
920         case AMDGPU_PP_SENSOR_GPU_LOAD:
921                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
922                                                        METRICS_AVERAGE_GFXACTIVITY,
923                                                        (uint32_t *)data);
924                 *size = 4;
925                 break;
926         case AMDGPU_PP_SENSOR_GPU_POWER:
927                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
928                                                        METRICS_AVERAGE_SOCKETPOWER,
929                                                        (uint32_t *)data);
930                 *size = 4;
931                 break;
932         case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
933                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
934                                                        METRICS_TEMPERATURE_HOTSPOT,
935                                                        (uint32_t *)data);
936                 *size = 4;
937                 break;
938         case AMDGPU_PP_SENSOR_EDGE_TEMP:
939                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
940                                                        METRICS_TEMPERATURE_EDGE,
941                                                        (uint32_t *)data);
942                 *size = 4;
943                 break;
944         case AMDGPU_PP_SENSOR_MEM_TEMP:
945                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
946                                                        METRICS_TEMPERATURE_MEM,
947                                                        (uint32_t *)data);
948                 *size = 4;
949                 break;
950         case AMDGPU_PP_SENSOR_GFX_MCLK:
951                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
952                                                        METRICS_CURR_UCLK,
953                                                        (uint32_t *)data);
954                 *(uint32_t *)data *= 100;
955                 *size = 4;
956                 break;
957         case AMDGPU_PP_SENSOR_GFX_SCLK:
958                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
959                                                        METRICS_AVERAGE_GFXCLK,
960                                                        (uint32_t *)data);
961                 *(uint32_t *)data *= 100;
962                 *size = 4;
963                 break;
964         case AMDGPU_PP_SENSOR_VDDGFX:
965                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
966                                                        METRICS_VOLTAGE_VDDGFX,
967                                                        (uint32_t *)data);
968                 *size = 4;
969                 break;
970         default:
971                 ret = -EOPNOTSUPP;
972                 break;
973         }
974
975         return ret;
976 }
977
978 static int smu_v13_0_7_get_current_clk_freq_by_table(struct smu_context *smu,
979                                                      enum smu_clk_type clk_type,
980                                                      uint32_t *value)
981 {
982         MetricsMember_t member_type;
983         int clk_id = 0;
984
985         clk_id = smu_cmn_to_asic_specific_index(smu,
986                                                 CMN2ASIC_MAPPING_CLK,
987                                                 clk_type);
988         if (clk_id < 0)
989                 return -EINVAL;
990
991         switch (clk_id) {
992         case PPCLK_GFXCLK:
993                 member_type = METRICS_AVERAGE_GFXCLK;
994                 break;
995         case PPCLK_UCLK:
996                 member_type = METRICS_CURR_UCLK;
997                 break;
998         case PPCLK_FCLK:
999                 member_type = METRICS_CURR_FCLK;
1000                 break;
1001         case PPCLK_SOCCLK:
1002                 member_type = METRICS_CURR_SOCCLK;
1003                 break;
1004         case PPCLK_VCLK_0:
1005                 member_type = METRICS_CURR_VCLK;
1006                 break;
1007         case PPCLK_DCLK_0:
1008                 member_type = METRICS_CURR_DCLK;
1009                 break;
1010         case PPCLK_VCLK_1:
1011                 member_type = METRICS_CURR_VCLK1;
1012                 break;
1013         case PPCLK_DCLK_1:
1014                 member_type = METRICS_CURR_DCLK1;
1015                 break;
1016         default:
1017                 return -EINVAL;
1018         }
1019
1020         return smu_v13_0_7_get_smu_metrics_data(smu,
1021                                                 member_type,
1022                                                 value);
1023 }
1024
1025 static bool smu_v13_0_7_is_od_feature_supported(struct smu_context *smu,
1026                                                 int od_feature_bit)
1027 {
1028         PPTable_t *pptable = smu->smu_table.driver_pptable;
1029         const OverDriveLimits_t * const overdrive_upperlimits =
1030                                 &pptable->SkuTable.OverDriveLimitsBasicMax;
1031
1032         return overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit);
1033 }
1034
1035 static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
1036                                               int od_feature_bit,
1037                                               bool lower_boundary,
1038                                               int32_t *min,
1039                                               int32_t *max)
1040 {
1041         PPTable_t *pptable = smu->smu_table.driver_pptable;
1042         const OverDriveLimits_t * const overdrive_upperlimits =
1043                                 &pptable->SkuTable.OverDriveLimitsBasicMax;
1044         const OverDriveLimits_t * const overdrive_lowerlimits =
1045                                 &pptable->SkuTable.OverDriveLimitsMin;
1046         int32_t od_min_setting, od_max_setting;
1047
1048         switch (od_feature_bit) {
1049         case PP_OD_FEATURE_GFXCLK_BIT:
1050                 if (lower_boundary) {
1051                         od_min_setting = overdrive_lowerlimits->GfxclkFmin;
1052                         od_max_setting = overdrive_upperlimits->GfxclkFmin;
1053                 } else {
1054                         od_min_setting = overdrive_lowerlimits->GfxclkFmax;
1055                         od_max_setting = overdrive_upperlimits->GfxclkFmax;
1056                 }
1057                 break;
1058         case PP_OD_FEATURE_UCLK_BIT:
1059                 if (lower_boundary) {
1060                         od_min_setting = overdrive_lowerlimits->UclkFmin;
1061                         od_max_setting = overdrive_upperlimits->UclkFmin;
1062                 } else {
1063                         od_min_setting = overdrive_lowerlimits->UclkFmax;
1064                         od_max_setting = overdrive_upperlimits->UclkFmax;
1065                 }
1066                 break;
1067         case PP_OD_FEATURE_GFX_VF_CURVE_BIT:
1068                 od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary;
1069                 od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary;
1070                 break;
1071         default:
1072                 break;
1073         }
1074
1075         if (min)
1076                 *min = od_min_setting;
1077         if (max)
1078                 *max = od_max_setting;
1079 }
1080
1081 static void smu_v13_0_7_dump_od_table(struct smu_context *smu,
1082                                       OverDriveTableExternal_t *od_table)
1083 {
1084         struct amdgpu_device *adev = smu->adev;
1085
1086         dev_dbg(adev->dev, "OD: Gfxclk: (%d, %d)\n", od_table->OverDriveTable.GfxclkFmin,
1087                                                      od_table->OverDriveTable.GfxclkFmax);
1088         dev_dbg(adev->dev, "OD: Uclk: (%d, %d)\n", od_table->OverDriveTable.UclkFmin,
1089                                                    od_table->OverDriveTable.UclkFmax);
1090 }
1091
1092 static int smu_v13_0_7_get_overdrive_table(struct smu_context *smu,
1093                                            OverDriveTableExternal_t *od_table)
1094 {
1095         int ret = 0;
1096
1097         ret = smu_cmn_update_table(smu,
1098                                    SMU_TABLE_OVERDRIVE,
1099                                    0,
1100                                    (void *)od_table,
1101                                    false);
1102         if (ret)
1103                 dev_err(smu->adev->dev, "Failed to get overdrive table!\n");
1104
1105         return ret;
1106 }
1107
1108 static int smu_v13_0_7_upload_overdrive_table(struct smu_context *smu,
1109                                               OverDriveTableExternal_t *od_table)
1110 {
1111         int ret = 0;
1112
1113         ret = smu_cmn_update_table(smu,
1114                                    SMU_TABLE_OVERDRIVE,
1115                                    0,
1116                                    (void *)od_table,
1117                                    true);
1118         if (ret)
1119                 dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
1120
1121         return ret;
1122 }
1123
1124 static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
1125                                         enum smu_clk_type clk_type,
1126                                         char *buf)
1127 {
1128         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
1129         struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1130         OverDriveTableExternal_t *od_table =
1131                 (OverDriveTableExternal_t *)smu->smu_table.overdrive_table;
1132         struct smu_13_0_dpm_table *single_dpm_table;
1133         struct smu_13_0_pcie_table *pcie_table;
1134         uint32_t gen_speed, lane_width;
1135         int i, curr_freq, size = 0;
1136         int32_t min_value, max_value;
1137         int ret = 0;
1138
1139         smu_cmn_get_sysfs_buf(&buf, &size);
1140
1141         if (amdgpu_ras_intr_triggered()) {
1142                 size += sysfs_emit_at(buf, size, "unavailable\n");
1143                 return size;
1144         }
1145
1146         switch (clk_type) {
1147         case SMU_SCLK:
1148                 single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
1149                 break;
1150         case SMU_MCLK:
1151                 single_dpm_table = &(dpm_context->dpm_tables.uclk_table);
1152                 break;
1153         case SMU_SOCCLK:
1154                 single_dpm_table = &(dpm_context->dpm_tables.soc_table);
1155                 break;
1156         case SMU_FCLK:
1157                 single_dpm_table = &(dpm_context->dpm_tables.fclk_table);
1158                 break;
1159         case SMU_VCLK:
1160         case SMU_VCLK1:
1161                 single_dpm_table = &(dpm_context->dpm_tables.vclk_table);
1162                 break;
1163         case SMU_DCLK:
1164         case SMU_DCLK1:
1165                 single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
1166                 break;
1167         default:
1168                 break;
1169         }
1170
1171         switch (clk_type) {
1172         case SMU_SCLK:
1173         case SMU_MCLK:
1174         case SMU_SOCCLK:
1175         case SMU_FCLK:
1176         case SMU_VCLK:
1177         case SMU_VCLK1:
1178         case SMU_DCLK:
1179         case SMU_DCLK1:
1180                 ret = smu_v13_0_7_get_current_clk_freq_by_table(smu, clk_type, &curr_freq);
1181                 if (ret) {
1182                         dev_err(smu->adev->dev, "Failed to get current clock freq!");
1183                         return ret;
1184                 }
1185
1186                 if (single_dpm_table->is_fine_grained) {
1187                         /*
1188                          * For fine grained dpms, there are only two dpm levels:
1189                          *   - level 0 -> min clock freq
1190                          *   - level 1 -> max clock freq
1191                          * And the current clock frequency can be any value between them.
1192                          * So, if the current clock frequency is not at level 0 or level 1,
1193                          * we will fake it as three dpm levels:
1194                          *   - level 0 -> min clock freq
1195                          *   - level 1 -> current actual clock freq
1196                          *   - level 2 -> max clock freq
1197                          */
1198                         if ((single_dpm_table->dpm_levels[0].value != curr_freq) &&
1199                              (single_dpm_table->dpm_levels[1].value != curr_freq)) {
1200                                 size += sysfs_emit_at(buf, size, "0: %uMhz\n",
1201                                                 single_dpm_table->dpm_levels[0].value);
1202                                 size += sysfs_emit_at(buf, size, "1: %uMhz *\n",
1203                                                 curr_freq);
1204                                 size += sysfs_emit_at(buf, size, "2: %uMhz\n",
1205                                                 single_dpm_table->dpm_levels[1].value);
1206                         } else {
1207                                 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n",
1208                                                 single_dpm_table->dpm_levels[0].value,
1209                                                 single_dpm_table->dpm_levels[0].value == curr_freq ? "*" : "");
1210                                 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
1211                                                 single_dpm_table->dpm_levels[1].value,
1212                                                 single_dpm_table->dpm_levels[1].value == curr_freq ? "*" : "");
1213                         }
1214                 } else {
1215                         for (i = 0; i < single_dpm_table->count; i++)
1216                                 size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
1217                                                 i, single_dpm_table->dpm_levels[i].value,
1218                                                 single_dpm_table->dpm_levels[i].value == curr_freq ? "*" : "");
1219                 }
1220                 break;
1221         case SMU_PCIE:
1222                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
1223                                                        METRICS_PCIE_RATE,
1224                                                        &gen_speed);
1225                 if (ret)
1226                         return ret;
1227
1228                 ret = smu_v13_0_7_get_smu_metrics_data(smu,
1229                                                        METRICS_PCIE_WIDTH,
1230                                                        &lane_width);
1231                 if (ret)
1232                         return ret;
1233
1234                 pcie_table = &(dpm_context->dpm_tables.pcie_table);
1235                 for (i = 0; i < pcie_table->num_of_link_levels; i++)
1236                         size += sysfs_emit_at(buf, size, "%d: %s %s %dMhz %s\n", i,
1237                                         (pcie_table->pcie_gen[i] == 0) ? "2.5GT/s," :
1238                                         (pcie_table->pcie_gen[i] == 1) ? "5.0GT/s," :
1239                                         (pcie_table->pcie_gen[i] == 2) ? "8.0GT/s," :
1240                                         (pcie_table->pcie_gen[i] == 3) ? "16.0GT/s," : "",
1241                                         (pcie_table->pcie_lane[i] == 1) ? "x1" :
1242                                         (pcie_table->pcie_lane[i] == 2) ? "x2" :
1243                                         (pcie_table->pcie_lane[i] == 3) ? "x4" :
1244                                         (pcie_table->pcie_lane[i] == 4) ? "x8" :
1245                                         (pcie_table->pcie_lane[i] == 5) ? "x12" :
1246                                         (pcie_table->pcie_lane[i] == 6) ? "x16" : "",
1247                                         pcie_table->clk_freq[i],
1248                                         (gen_speed == DECODE_GEN_SPEED(pcie_table->pcie_gen[i])) &&
1249                                         (lane_width == DECODE_LANE_WIDTH(pcie_table->pcie_lane[i])) ?
1250                                         "*" : "");
1251                 break;
1252
1253         case SMU_OD_SCLK:
1254                 if (!smu_v13_0_7_is_od_feature_supported(smu,
1255                                                          PP_OD_FEATURE_GFXCLK_BIT))
1256                         break;
1257
1258                 size += sysfs_emit_at(buf, size, "OD_SCLK:\n");
1259                 size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n",
1260                                         od_table->OverDriveTable.GfxclkFmin,
1261                                         od_table->OverDriveTable.GfxclkFmax);
1262                 break;
1263
1264         case SMU_OD_MCLK:
1265                 if (!smu_v13_0_7_is_od_feature_supported(smu,
1266                                                          PP_OD_FEATURE_UCLK_BIT))
1267                         break;
1268
1269                 size += sysfs_emit_at(buf, size, "OD_MCLK:\n");
1270                 size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMHz\n",
1271                                         od_table->OverDriveTable.UclkFmin,
1272                                         od_table->OverDriveTable.UclkFmax);
1273                 break;
1274
1275         case SMU_OD_VDDC_CURVE:
1276                 if (!smu_v13_0_7_is_od_feature_supported(smu,
1277                                                          PP_OD_FEATURE_GFX_VF_CURVE_BIT))
1278                         break;
1279
1280                 size += sysfs_emit_at(buf, size, "OD_VDDC_CURVE:\n");
1281                 for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
1282                         size += sysfs_emit_at(buf, size, "%d: %dmv\n",
1283                                                 i,
1284                                                 od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i]);
1285                 break;
1286
1287         case SMU_OD_RANGE:
1288                 if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
1289                     !smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
1290                     !smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT))
1291                         break;
1292
1293                 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1294
1295                 if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) {
1296                         smu_v13_0_7_get_od_setting_limits(smu,
1297                                                           PP_OD_FEATURE_GFXCLK_BIT,
1298                                                           true,
1299                                                           &min_value,
1300                                                           NULL);
1301                         smu_v13_0_7_get_od_setting_limits(smu,
1302                                                           PP_OD_FEATURE_GFXCLK_BIT,
1303                                                           false,
1304                                                           NULL,
1305                                                           &max_value);
1306                         size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
1307                                               min_value, max_value);
1308                 }
1309
1310                 if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) {
1311                         smu_v13_0_7_get_od_setting_limits(smu,
1312                                                           PP_OD_FEATURE_UCLK_BIT,
1313                                                           true,
1314                                                           &min_value,
1315                                                           NULL);
1316                         smu_v13_0_7_get_od_setting_limits(smu,
1317                                                           PP_OD_FEATURE_UCLK_BIT,
1318                                                           false,
1319                                                           NULL,
1320                                                           &max_value);
1321                         size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n",
1322                                               min_value, max_value);
1323                 }
1324
1325                 if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
1326                         smu_v13_0_7_get_od_setting_limits(smu,
1327                                                           PP_OD_FEATURE_GFX_VF_CURVE_BIT,
1328                                                           true,
1329                                                           &min_value,
1330                                                           &max_value);
1331                         size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n",
1332                                               min_value, max_value);
1333                 }
1334                 break;
1335
1336         default:
1337                 break;
1338         }
1339
1340         return size;
1341 }
1342
1343 static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
1344                                          enum PP_OD_DPM_TABLE_COMMAND type,
1345                                          long input[],
1346                                          uint32_t size)
1347 {
1348         struct smu_table_context *table_context = &smu->smu_table;
1349         OverDriveTableExternal_t *od_table =
1350                 (OverDriveTableExternal_t *)table_context->overdrive_table;
1351         struct amdgpu_device *adev = smu->adev;
1352         uint32_t offset_of_featurectrlmask;
1353         int32_t minimum, maximum;
1354         uint32_t feature_ctrlmask;
1355         int i, ret = 0;
1356
1357         switch (type) {
1358         case PP_OD_EDIT_SCLK_VDDC_TABLE:
1359                 if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) {
1360                         dev_warn(adev->dev, "GFXCLK_LIMITS setting not supported!\n");
1361                         return -ENOTSUPP;
1362                 }
1363
1364                 for (i = 0; i < size; i += 2) {
1365                         if (i + 2 > size) {
1366                                 dev_info(adev->dev, "invalid number of input parameters %d\n", size);
1367                                 return -EINVAL;
1368                         }
1369
1370                         switch (input[i]) {
1371                         case 0:
1372                                 smu_v13_0_7_get_od_setting_limits(smu,
1373                                                                   PP_OD_FEATURE_GFXCLK_BIT,
1374                                                                   true,
1375                                                                   &minimum,
1376                                                                   &maximum);
1377                                 if (input[i + 1] < minimum ||
1378                                     input[i + 1] > maximum) {
1379                                         dev_info(adev->dev, "GfxclkFmin (%ld) must be within [%u, %u]!\n",
1380                                                 input[i + 1], minimum, maximum);
1381                                         return -EINVAL;
1382                                 }
1383
1384                                 od_table->OverDriveTable.GfxclkFmin = input[i + 1];
1385                                 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFXCLK_BIT;
1386                                 break;
1387
1388                         case 1:
1389                                 smu_v13_0_7_get_od_setting_limits(smu,
1390                                                                   PP_OD_FEATURE_GFXCLK_BIT,
1391                                                                   false,
1392                                                                   &minimum,
1393                                                                   &maximum);
1394                                 if (input[i + 1] < minimum ||
1395                                     input[i + 1] > maximum) {
1396                                         dev_info(adev->dev, "GfxclkFmax (%ld) must be within [%u, %u]!\n",
1397                                                 input[i + 1], minimum, maximum);
1398                                         return -EINVAL;
1399                                 }
1400
1401                                 od_table->OverDriveTable.GfxclkFmax = input[i + 1];
1402                                 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFXCLK_BIT;
1403                                 break;
1404
1405                         default:
1406                                 dev_info(adev->dev, "Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
1407                                 dev_info(adev->dev, "Supported indices: [0:min,1:max]\n");
1408                                 return -EINVAL;
1409                         }
1410                 }
1411
1412                 if (od_table->OverDriveTable.GfxclkFmin > od_table->OverDriveTable.GfxclkFmax) {
1413                         dev_err(adev->dev,
1414                                 "Invalid setting: GfxclkFmin(%u) is bigger than GfxclkFmax(%u)\n",
1415                                 (uint32_t)od_table->OverDriveTable.GfxclkFmin,
1416                                 (uint32_t)od_table->OverDriveTable.GfxclkFmax);
1417                         return -EINVAL;
1418                 }
1419                 break;
1420
1421         case PP_OD_EDIT_MCLK_VDDC_TABLE:
1422                 if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) {
1423                         dev_warn(adev->dev, "UCLK_LIMITS setting not supported!\n");
1424                         return -ENOTSUPP;
1425                 }
1426
1427                 for (i = 0; i < size; i += 2) {
1428                         if (i + 2 > size) {
1429                                 dev_info(adev->dev, "invalid number of input parameters %d\n", size);
1430                                 return -EINVAL;
1431                         }
1432
1433                         switch (input[i]) {
1434                         case 0:
1435                                 smu_v13_0_7_get_od_setting_limits(smu,
1436                                                                   PP_OD_FEATURE_UCLK_BIT,
1437                                                                   true,
1438                                                                   &minimum,
1439                                                                   &maximum);
1440                                 if (input[i + 1] < minimum ||
1441                                     input[i + 1] > maximum) {
1442                                         dev_info(adev->dev, "UclkFmin (%ld) must be within [%u, %u]!\n",
1443                                                 input[i + 1], minimum, maximum);
1444                                         return -EINVAL;
1445                                 }
1446
1447                                 od_table->OverDriveTable.UclkFmin = input[i + 1];
1448                                 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_UCLK_BIT;
1449                                 break;
1450
1451                         case 1:
1452                                 smu_v13_0_7_get_od_setting_limits(smu,
1453                                                                   PP_OD_FEATURE_UCLK_BIT,
1454                                                                   false,
1455                                                                   &minimum,
1456                                                                   &maximum);
1457                                 if (input[i + 1] < minimum ||
1458                                     input[i + 1] > maximum) {
1459                                         dev_info(adev->dev, "UclkFmax (%ld) must be within [%u, %u]!\n",
1460                                                 input[i + 1], minimum, maximum);
1461                                         return -EINVAL;
1462                                 }
1463
1464                                 od_table->OverDriveTable.UclkFmax = input[i + 1];
1465                                 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_UCLK_BIT;
1466                                 break;
1467
1468                         default:
1469                                 dev_info(adev->dev, "Invalid MCLK_VDDC_TABLE index: %ld\n", input[i]);
1470                                 dev_info(adev->dev, "Supported indices: [0:min,1:max]\n");
1471                                 return -EINVAL;
1472                         }
1473                 }
1474
1475                 if (od_table->OverDriveTable.UclkFmin > od_table->OverDriveTable.UclkFmax) {
1476                         dev_err(adev->dev,
1477                                 "Invalid setting: UclkFmin(%u) is bigger than UclkFmax(%u)\n",
1478                                 (uint32_t)od_table->OverDriveTable.UclkFmin,
1479                                 (uint32_t)od_table->OverDriveTable.UclkFmax);
1480                         return -EINVAL;
1481                 }
1482                 break;
1483
1484         case PP_OD_EDIT_VDDC_CURVE:
1485                 if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
1486                         dev_warn(adev->dev, "VF curve setting not supported!\n");
1487                         return -ENOTSUPP;
1488                 }
1489
1490                 if (input[0] >= PP_NUM_OD_VF_CURVE_POINTS ||
1491                     input[0] < 0)
1492                         return -EINVAL;
1493
1494                 smu_v13_0_7_get_od_setting_limits(smu,
1495                                                   PP_OD_FEATURE_GFX_VF_CURVE_BIT,
1496                                                   true,
1497                                                   &minimum,
1498                                                   &maximum);
1499                 if (input[1] < minimum ||
1500                     input[1] > maximum) {
1501                         dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n",
1502                                  input[1], minimum, maximum);
1503                         return -EINVAL;
1504                 }
1505
1506                 od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[input[0]] = input[1];
1507                 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT;
1508                 break;
1509
1510         case PP_OD_RESTORE_DEFAULT_TABLE:
1511                 feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask;
1512                 memcpy(od_table,
1513                        table_context->boot_overdrive_table,
1514                        sizeof(OverDriveTableExternal_t));
1515                 od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask;
1516                 fallthrough;
1517
1518         case PP_OD_COMMIT_DPM_TABLE:
1519                 /*
1520                  * The member below instructs PMFW the settings focused in
1521                  * this single operation.
1522                  * `uint32_t FeatureCtrlMask;`
1523                  * It does not contain actual informations about user's custom
1524                  * settings. Thus we do not cache it.
1525                  */
1526                 offset_of_featurectrlmask = offsetof(OverDriveTable_t, FeatureCtrlMask);
1527                 if (memcmp((u8 *)od_table + offset_of_featurectrlmask,
1528                            table_context->user_overdrive_table + offset_of_featurectrlmask,
1529                            sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask)) {
1530                         smu_v13_0_7_dump_od_table(smu, od_table);
1531
1532                         ret = smu_v13_0_7_upload_overdrive_table(smu, od_table);
1533                         if (ret) {
1534                                 dev_err(adev->dev, "Failed to upload overdrive table!\n");
1535                                 return ret;
1536                         }
1537
1538                         od_table->OverDriveTable.FeatureCtrlMask = 0;
1539                         memcpy(table_context->user_overdrive_table + offset_of_featurectrlmask,
1540                                (u8 *)od_table + offset_of_featurectrlmask,
1541                                sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask);
1542
1543                         if (!memcmp(table_context->user_overdrive_table,
1544                                     table_context->boot_overdrive_table,
1545                                     sizeof(OverDriveTableExternal_t)))
1546                                 smu->user_dpm_profile.user_od = false;
1547                         else
1548                                 smu->user_dpm_profile.user_od = true;
1549                 }
1550                 break;
1551
1552         default:
1553                 return -ENOSYS;
1554         }
1555
1556         return ret;
1557 }
1558
1559 static int smu_v13_0_7_force_clk_levels(struct smu_context *smu,
1560                                         enum smu_clk_type clk_type,
1561                                         uint32_t mask)
1562 {
1563         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
1564         struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1565         struct smu_13_0_dpm_table *single_dpm_table;
1566         uint32_t soft_min_level, soft_max_level;
1567         uint32_t min_freq, max_freq;
1568         int ret = 0;
1569
1570         soft_min_level = mask ? (ffs(mask) - 1) : 0;
1571         soft_max_level = mask ? (fls(mask) - 1) : 0;
1572
1573         switch (clk_type) {
1574         case SMU_GFXCLK:
1575         case SMU_SCLK:
1576                 single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
1577                 break;
1578         case SMU_MCLK:
1579         case SMU_UCLK:
1580                 single_dpm_table = &(dpm_context->dpm_tables.uclk_table);
1581                 break;
1582         case SMU_SOCCLK:
1583                 single_dpm_table = &(dpm_context->dpm_tables.soc_table);
1584                 break;
1585         case SMU_FCLK:
1586                 single_dpm_table = &(dpm_context->dpm_tables.fclk_table);
1587                 break;
1588         case SMU_VCLK:
1589         case SMU_VCLK1:
1590                 single_dpm_table = &(dpm_context->dpm_tables.vclk_table);
1591                 break;
1592         case SMU_DCLK:
1593         case SMU_DCLK1:
1594                 single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
1595                 break;
1596         default:
1597                 break;
1598         }
1599
1600         switch (clk_type) {
1601         case SMU_GFXCLK:
1602         case SMU_SCLK:
1603         case SMU_MCLK:
1604         case SMU_UCLK:
1605         case SMU_SOCCLK:
1606         case SMU_FCLK:
1607         case SMU_VCLK:
1608         case SMU_VCLK1:
1609         case SMU_DCLK:
1610         case SMU_DCLK1:
1611                 if (single_dpm_table->is_fine_grained) {
1612                         /* There is only 2 levels for fine grained DPM */
1613                         soft_max_level = (soft_max_level >= 1 ? 1 : 0);
1614                         soft_min_level = (soft_min_level >= 1 ? 1 : 0);
1615                 } else {
1616                         if ((soft_max_level >= single_dpm_table->count) ||
1617                             (soft_min_level >= single_dpm_table->count))
1618                                 return -EINVAL;
1619                 }
1620
1621                 min_freq = single_dpm_table->dpm_levels[soft_min_level].value;
1622                 max_freq = single_dpm_table->dpm_levels[soft_max_level].value;
1623
1624                 ret = smu_v13_0_set_soft_freq_limited_range(smu,
1625                                                             clk_type,
1626                                                             min_freq,
1627                                                             max_freq);
1628                 break;
1629         case SMU_DCEFCLK:
1630         case SMU_PCIE:
1631         default:
1632                 break;
1633         }
1634
1635         return ret;
1636 }
1637
1638 static const struct smu_temperature_range smu13_thermal_policy[] =
1639 {
1640         {-273150,  99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000},
1641         { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000},
1642 };
1643
1644 static int smu_v13_0_7_get_thermal_temperature_range(struct smu_context *smu,
1645                                                      struct smu_temperature_range *range)
1646 {
1647         struct smu_table_context *table_context = &smu->smu_table;
1648         struct smu_13_0_7_powerplay_table *powerplay_table =
1649                 table_context->power_play_table;
1650         PPTable_t *pptable = smu->smu_table.driver_pptable;
1651
1652         if (!range)
1653                 return -EINVAL;
1654
1655         memcpy(range, &smu13_thermal_policy[0], sizeof(struct smu_temperature_range));
1656
1657         range->max = pptable->SkuTable.TemperatureLimit[TEMP_EDGE] *
1658                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1659         range->edge_emergency_max = (pptable->SkuTable.TemperatureLimit[TEMP_EDGE] + CTF_OFFSET_EDGE) *
1660                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1661         range->hotspot_crit_max = pptable->SkuTable.TemperatureLimit[TEMP_HOTSPOT] *
1662                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1663         range->hotspot_emergency_max = (pptable->SkuTable.TemperatureLimit[TEMP_HOTSPOT] + CTF_OFFSET_HOTSPOT) *
1664                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1665         range->mem_crit_max = pptable->SkuTable.TemperatureLimit[TEMP_MEM] *
1666                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1667         range->mem_emergency_max = (pptable->SkuTable.TemperatureLimit[TEMP_MEM] + CTF_OFFSET_MEM)*
1668                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1669         range->software_shutdown_temp = powerplay_table->software_shutdown_temp;
1670         range->software_shutdown_temp_offset = pptable->SkuTable.FanAbnormalTempLimitOffset;
1671
1672         return 0;
1673 }
1674
1675 #define MAX(a, b)       ((a) > (b) ? (a) : (b))
1676 static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu,
1677                                            void **table)
1678 {
1679         struct smu_table_context *smu_table = &smu->smu_table;
1680         struct gpu_metrics_v1_3 *gpu_metrics =
1681                 (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
1682         SmuMetricsExternal_t metrics_ext;
1683         SmuMetrics_t *metrics = &metrics_ext.SmuMetrics;
1684         int ret = 0;
1685
1686         ret = smu_cmn_get_metrics_table(smu,
1687                                         &metrics_ext,
1688                                         true);
1689         if (ret)
1690                 return ret;
1691
1692         smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
1693
1694         gpu_metrics->temperature_edge = metrics->AvgTemperature[TEMP_EDGE];
1695         gpu_metrics->temperature_hotspot = metrics->AvgTemperature[TEMP_HOTSPOT];
1696         gpu_metrics->temperature_mem = metrics->AvgTemperature[TEMP_MEM];
1697         gpu_metrics->temperature_vrgfx = metrics->AvgTemperature[TEMP_VR_GFX];
1698         gpu_metrics->temperature_vrsoc = metrics->AvgTemperature[TEMP_VR_SOC];
1699         gpu_metrics->temperature_vrmem = MAX(metrics->AvgTemperature[TEMP_VR_MEM0],
1700                                              metrics->AvgTemperature[TEMP_VR_MEM1]);
1701
1702         gpu_metrics->average_gfx_activity = metrics->AverageGfxActivity;
1703         gpu_metrics->average_umc_activity = metrics->AverageUclkActivity;
1704         gpu_metrics->average_mm_activity = MAX(metrics->Vcn0ActivityPercentage,
1705                                                metrics->Vcn1ActivityPercentage);
1706
1707         gpu_metrics->average_socket_power = metrics->AverageSocketPower;
1708         gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
1709
1710         if (metrics->AverageGfxActivity <= SMU_13_0_7_BUSY_THRESHOLD)
1711                 gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
1712         else
1713                 gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPreDs;
1714
1715         if (metrics->AverageUclkActivity <= SMU_13_0_7_BUSY_THRESHOLD)
1716                 gpu_metrics->average_uclk_frequency = metrics->AverageMemclkFrequencyPostDs;
1717         else
1718                 gpu_metrics->average_uclk_frequency = metrics->AverageMemclkFrequencyPreDs;
1719
1720         gpu_metrics->average_vclk0_frequency = metrics->AverageVclk0Frequency;
1721         gpu_metrics->average_dclk0_frequency = metrics->AverageDclk0Frequency;
1722         gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency;
1723         gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency;
1724
1725         gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK];
1726         gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0];
1727         gpu_metrics->current_dclk0 = metrics->CurrClock[PPCLK_DCLK_0];
1728         gpu_metrics->current_vclk1 = metrics->CurrClock[PPCLK_VCLK_1];
1729         gpu_metrics->current_dclk1 = metrics->CurrClock[PPCLK_DCLK_1];
1730
1731         gpu_metrics->throttle_status =
1732                         smu_v13_0_7_get_throttler_status(metrics);
1733         gpu_metrics->indep_throttle_status =
1734                         smu_cmn_get_indep_throttler_status(gpu_metrics->throttle_status,
1735                                                            smu_v13_0_7_throttler_map);
1736
1737         gpu_metrics->current_fan_speed = metrics->AvgFanRpm;
1738
1739         gpu_metrics->pcie_link_width = metrics->PcieWidth;
1740         gpu_metrics->pcie_link_speed = metrics->PcieRate;
1741
1742         gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
1743
1744         gpu_metrics->voltage_gfx = metrics->AvgVoltage[SVI_PLANE_GFX];
1745         gpu_metrics->voltage_soc = metrics->AvgVoltage[SVI_PLANE_SOC];
1746         gpu_metrics->voltage_mem = metrics->AvgVoltage[SVI_PLANE_VMEMP];
1747
1748         *table = (void *)gpu_metrics;
1749
1750         return sizeof(struct gpu_metrics_v1_3);
1751 }
1752
1753 static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
1754 {
1755         OverDriveTableExternal_t *od_table =
1756                 (OverDriveTableExternal_t *)smu->smu_table.overdrive_table;
1757         OverDriveTableExternal_t *boot_od_table =
1758                 (OverDriveTableExternal_t *)smu->smu_table.boot_overdrive_table;
1759         OverDriveTableExternal_t *user_od_table =
1760                 (OverDriveTableExternal_t *)smu->smu_table.user_overdrive_table;
1761         OverDriveTableExternal_t user_od_table_bak;
1762         int ret = 0;
1763         int i;
1764
1765         ret = smu_v13_0_7_get_overdrive_table(smu, boot_od_table);
1766         if (ret)
1767                 return ret;
1768
1769         smu_v13_0_7_dump_od_table(smu, boot_od_table);
1770
1771         memcpy(od_table,
1772                boot_od_table,
1773                sizeof(OverDriveTableExternal_t));
1774
1775         /*
1776          * For S3/S4/Runpm resume, we need to setup those overdrive tables again,
1777          * but we have to preserve user defined values in "user_od_table".
1778          */
1779         if (!smu->adev->in_suspend) {
1780                 memcpy(user_od_table,
1781                        boot_od_table,
1782                        sizeof(OverDriveTableExternal_t));
1783                 smu->user_dpm_profile.user_od = false;
1784         } else if (smu->user_dpm_profile.user_od) {
1785                 memcpy(&user_od_table_bak,
1786                        user_od_table,
1787                        sizeof(OverDriveTableExternal_t));
1788                 memcpy(user_od_table,
1789                        boot_od_table,
1790                        sizeof(OverDriveTableExternal_t));
1791                 user_od_table->OverDriveTable.GfxclkFmin =
1792                                 user_od_table_bak.OverDriveTable.GfxclkFmin;
1793                 user_od_table->OverDriveTable.GfxclkFmax =
1794                                 user_od_table_bak.OverDriveTable.GfxclkFmax;
1795                 user_od_table->OverDriveTable.UclkFmin =
1796                                 user_od_table_bak.OverDriveTable.UclkFmin;
1797                 user_od_table->OverDriveTable.UclkFmax =
1798                                 user_od_table_bak.OverDriveTable.UclkFmax;
1799                 for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
1800                         user_od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] =
1801                                 user_od_table_bak.OverDriveTable.VoltageOffsetPerZoneBoundary[i];
1802         }
1803
1804         return 0;
1805 }
1806
1807 static int smu_v13_0_7_restore_user_od_settings(struct smu_context *smu)
1808 {
1809         struct smu_table_context *table_context = &smu->smu_table;
1810         OverDriveTableExternal_t *od_table = table_context->overdrive_table;
1811         OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table;
1812         int res;
1813
1814         user_od_table->OverDriveTable.FeatureCtrlMask = 1U << PP_OD_FEATURE_GFXCLK_BIT |
1815                                                         1U << PP_OD_FEATURE_UCLK_BIT |
1816                                                         1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT;
1817         res = smu_v13_0_7_upload_overdrive_table(smu, user_od_table);
1818         user_od_table->OverDriveTable.FeatureCtrlMask = 0;
1819         if (res == 0)
1820                 memcpy(od_table, user_od_table, sizeof(OverDriveTableExternal_t));
1821
1822         return res;
1823 }
1824
1825 static int smu_v13_0_7_populate_umd_state_clk(struct smu_context *smu)
1826 {
1827         struct smu_13_0_dpm_context *dpm_context =
1828                                 smu->smu_dpm.dpm_context;
1829         struct smu_13_0_dpm_table *gfx_table =
1830                                 &dpm_context->dpm_tables.gfx_table;
1831         struct smu_13_0_dpm_table *mem_table =
1832                                 &dpm_context->dpm_tables.uclk_table;
1833         struct smu_13_0_dpm_table *soc_table =
1834                                 &dpm_context->dpm_tables.soc_table;
1835         struct smu_13_0_dpm_table *vclk_table =
1836                                 &dpm_context->dpm_tables.vclk_table;
1837         struct smu_13_0_dpm_table *dclk_table =
1838                                 &dpm_context->dpm_tables.dclk_table;
1839         struct smu_13_0_dpm_table *fclk_table =
1840                                 &dpm_context->dpm_tables.fclk_table;
1841         struct smu_umd_pstate_table *pstate_table =
1842                                 &smu->pstate_table;
1843         struct smu_table_context *table_context = &smu->smu_table;
1844         PPTable_t *pptable = table_context->driver_pptable;
1845         DriverReportedClocks_t driver_clocks =
1846                 pptable->SkuTable.DriverReportedClocks;
1847
1848         pstate_table->gfxclk_pstate.min = gfx_table->min;
1849         if (driver_clocks.GameClockAc &&
1850                 (driver_clocks.GameClockAc < gfx_table->max))
1851                 pstate_table->gfxclk_pstate.peak = driver_clocks.GameClockAc;
1852         else
1853                 pstate_table->gfxclk_pstate.peak = gfx_table->max;
1854
1855         pstate_table->uclk_pstate.min = mem_table->min;
1856         pstate_table->uclk_pstate.peak = mem_table->max;
1857
1858         pstate_table->socclk_pstate.min = soc_table->min;
1859         pstate_table->socclk_pstate.peak = soc_table->max;
1860
1861         pstate_table->vclk_pstate.min = vclk_table->min;
1862         pstate_table->vclk_pstate.peak = vclk_table->max;
1863
1864         pstate_table->dclk_pstate.min = dclk_table->min;
1865         pstate_table->dclk_pstate.peak = dclk_table->max;
1866
1867         pstate_table->fclk_pstate.min = fclk_table->min;
1868         pstate_table->fclk_pstate.peak = fclk_table->max;
1869
1870         if (driver_clocks.BaseClockAc &&
1871                 driver_clocks.BaseClockAc < gfx_table->max)
1872                 pstate_table->gfxclk_pstate.standard = driver_clocks.BaseClockAc;
1873         else
1874                 pstate_table->gfxclk_pstate.standard = gfx_table->max;
1875         pstate_table->uclk_pstate.standard = mem_table->max;
1876         pstate_table->socclk_pstate.standard = soc_table->min;
1877         pstate_table->vclk_pstate.standard = vclk_table->min;
1878         pstate_table->dclk_pstate.standard = dclk_table->min;
1879         pstate_table->fclk_pstate.standard = fclk_table->min;
1880
1881         return 0;
1882 }
1883
1884 static int smu_v13_0_7_get_fan_speed_pwm(struct smu_context *smu,
1885                                          uint32_t *speed)
1886 {
1887         int ret;
1888
1889         if (!speed)
1890                 return -EINVAL;
1891
1892         ret = smu_v13_0_7_get_smu_metrics_data(smu,
1893                                                METRICS_CURR_FANPWM,
1894                                                speed);
1895         if (ret) {
1896                 dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
1897                 return ret;
1898         }
1899
1900         /* Convert the PMFW output which is in percent to pwm(255) based */
1901         *speed = MIN(*speed * 255 / 100, 255);
1902
1903         return 0;
1904 }
1905
1906 static int smu_v13_0_7_get_fan_speed_rpm(struct smu_context *smu,
1907                                          uint32_t *speed)
1908 {
1909         if (!speed)
1910                 return -EINVAL;
1911
1912         return smu_v13_0_7_get_smu_metrics_data(smu,
1913                                                 METRICS_CURR_FANSPEED,
1914                                                 speed);
1915 }
1916
1917 static int smu_v13_0_7_enable_mgpu_fan_boost(struct smu_context *smu)
1918 {
1919         struct smu_table_context *table_context = &smu->smu_table;
1920         PPTable_t *pptable = table_context->driver_pptable;
1921         SkuTable_t *skutable = &pptable->SkuTable;
1922
1923         /*
1924          * Skip the MGpuFanBoost setting for those ASICs
1925          * which do not support it
1926          */
1927         if (skutable->MGpuAcousticLimitRpmThreshold == 0)
1928                 return 0;
1929
1930         return smu_cmn_send_smc_msg_with_param(smu,
1931                                                SMU_MSG_SetMGpuFanBoostLimitRpm,
1932                                                0,
1933                                                NULL);
1934 }
1935
1936 static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
1937                                        uint32_t *current_power_limit,
1938                                        uint32_t *default_power_limit,
1939                                        uint32_t *max_power_limit)
1940 {
1941         struct smu_table_context *table_context = &smu->smu_table;
1942         struct smu_13_0_7_powerplay_table *powerplay_table =
1943                 (struct smu_13_0_7_powerplay_table *)table_context->power_play_table;
1944         PPTable_t *pptable = table_context->driver_pptable;
1945         SkuTable_t *skutable = &pptable->SkuTable;
1946         uint32_t power_limit, od_percent;
1947
1948         if (smu_v13_0_get_current_power_limit(smu, &power_limit))
1949                 power_limit = smu->adev->pm.ac_power ?
1950                               skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
1951                               skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
1952
1953         if (current_power_limit)
1954                 *current_power_limit = power_limit;
1955         if (default_power_limit)
1956                 *default_power_limit = power_limit;
1957
1958         if (max_power_limit) {
1959                 if (smu->od_enabled) {
1960                         od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
1961
1962                         dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
1963
1964                         power_limit *= (100 + od_percent);
1965                         power_limit /= 100;
1966                 }
1967                 *max_power_limit = power_limit;
1968         }
1969
1970         return 0;
1971 }
1972
1973 static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf)
1974 {
1975         DpmActivityMonitorCoeffIntExternal_t *activity_monitor_external;
1976         uint32_t i, j, size = 0;
1977         int16_t workload_type = 0;
1978         int result = 0;
1979
1980         if (!buf)
1981                 return -EINVAL;
1982
1983         activity_monitor_external = kcalloc(PP_SMC_POWER_PROFILE_COUNT,
1984                                             sizeof(*activity_monitor_external),
1985                                             GFP_KERNEL);
1986         if (!activity_monitor_external)
1987                 return -ENOMEM;
1988
1989         size += sysfs_emit_at(buf, size, "                              ");
1990         for (i = 0; i <= PP_SMC_POWER_PROFILE_WINDOW3D; i++)
1991                 size += sysfs_emit_at(buf, size, "%-14s%s", amdgpu_pp_profile_name[i],
1992                         (i == smu->power_profile_mode) ? "* " : "  ");
1993
1994         size += sysfs_emit_at(buf, size, "\n");
1995
1996         for (i = 0; i <= PP_SMC_POWER_PROFILE_WINDOW3D; i++) {
1997                 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1998                 workload_type = smu_cmn_to_asic_specific_index(smu,
1999                                                                CMN2ASIC_MAPPING_WORKLOAD,
2000                                                                i);
2001                 if (workload_type == -ENOTSUPP)
2002                         continue;
2003                 else if (workload_type < 0) {
2004                         result = -EINVAL;
2005                         goto out;
2006                 }
2007
2008                 result = smu_cmn_update_table(smu,
2009                                           SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
2010                                           (void *)(&activity_monitor_external[i]), false);
2011                 if (result) {
2012                         dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
2013                         goto out;
2014                 }
2015         }
2016
2017 #define PRINT_DPM_MONITOR(field)                                                                        \
2018 do {                                                                                                    \
2019         size += sysfs_emit_at(buf, size, "%-30s", #field);                                              \
2020         for (j = 0; j <= PP_SMC_POWER_PROFILE_WINDOW3D; j++)                                            \
2021                 size += sysfs_emit_at(buf, size, "%-16d", activity_monitor_external[j].DpmActivityMonitorCoeffInt.field);               \
2022         size += sysfs_emit_at(buf, size, "\n");                                                         \
2023 } while (0)
2024
2025         PRINT_DPM_MONITOR(Gfx_ActiveHystLimit);
2026         PRINT_DPM_MONITOR(Gfx_IdleHystLimit);
2027         PRINT_DPM_MONITOR(Gfx_FPS);
2028         PRINT_DPM_MONITOR(Gfx_MinActiveFreqType);
2029         PRINT_DPM_MONITOR(Gfx_BoosterFreqType);
2030         PRINT_DPM_MONITOR(Gfx_MinActiveFreq);
2031         PRINT_DPM_MONITOR(Gfx_BoosterFreq);
2032         PRINT_DPM_MONITOR(Fclk_ActiveHystLimit);
2033         PRINT_DPM_MONITOR(Fclk_IdleHystLimit);
2034         PRINT_DPM_MONITOR(Fclk_FPS);
2035         PRINT_DPM_MONITOR(Fclk_MinActiveFreqType);
2036         PRINT_DPM_MONITOR(Fclk_BoosterFreqType);
2037         PRINT_DPM_MONITOR(Fclk_MinActiveFreq);
2038         PRINT_DPM_MONITOR(Fclk_BoosterFreq);
2039 #undef PRINT_DPM_MONITOR
2040
2041         result = size;
2042 out:
2043         kfree(activity_monitor_external);
2044         return result;
2045 }
2046
2047 static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
2048 {
2049
2050         DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
2051         DpmActivityMonitorCoeffInt_t *activity_monitor =
2052                 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
2053         int workload_type, ret = 0;
2054
2055         smu->power_profile_mode = input[size];
2056
2057         if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_WINDOW3D) {
2058                 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);
2059                 return -EINVAL;
2060         }
2061
2062         if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
2063
2064                 ret = smu_cmn_update_table(smu,
2065                                        SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
2066                                        (void *)(&activity_monitor_external), false);
2067                 if (ret) {
2068                         dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
2069                         return ret;
2070                 }
2071
2072                 switch (input[0]) {
2073                 case 0: /* Gfxclk */
2074                         activity_monitor->Gfx_ActiveHystLimit = input[1];
2075                         activity_monitor->Gfx_IdleHystLimit = input[2];
2076                         activity_monitor->Gfx_FPS = input[3];
2077                         activity_monitor->Gfx_MinActiveFreqType = input[4];
2078                         activity_monitor->Gfx_BoosterFreqType = input[5];
2079                         activity_monitor->Gfx_MinActiveFreq = input[6];
2080                         activity_monitor->Gfx_BoosterFreq = input[7];
2081                         break;
2082                 case 1: /* Fclk */
2083                         activity_monitor->Fclk_ActiveHystLimit = input[1];
2084                         activity_monitor->Fclk_IdleHystLimit = input[2];
2085                         activity_monitor->Fclk_FPS = input[3];
2086                         activity_monitor->Fclk_MinActiveFreqType = input[4];
2087                         activity_monitor->Fclk_BoosterFreqType = input[5];
2088                         activity_monitor->Fclk_MinActiveFreq = input[6];
2089                         activity_monitor->Fclk_BoosterFreq = input[7];
2090                         break;
2091                 }
2092
2093                 ret = smu_cmn_update_table(smu,
2094                                        SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
2095                                        (void *)(&activity_monitor_external), true);
2096                 if (ret) {
2097                         dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
2098                         return ret;
2099                 }
2100         }
2101
2102         /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
2103         workload_type = smu_cmn_to_asic_specific_index(smu,
2104                                                        CMN2ASIC_MAPPING_WORKLOAD,
2105                                                        smu->power_profile_mode);
2106         if (workload_type < 0)
2107                 return -EINVAL;
2108         smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
2109                                     1 << workload_type, NULL);
2110
2111         return ret;
2112 }
2113
2114 static int smu_v13_0_7_set_mp1_state(struct smu_context *smu,
2115                                      enum pp_mp1_state mp1_state)
2116 {
2117         int ret;
2118
2119         switch (mp1_state) {
2120         case PP_MP1_STATE_UNLOAD:
2121                 ret = smu_cmn_set_mp1_state(smu, mp1_state);
2122                 break;
2123         default:
2124                 /* Ignore others */
2125                 ret = 0;
2126         }
2127
2128         return ret;
2129 }
2130
2131 static int smu_v13_0_7_baco_enter(struct smu_context *smu)
2132 {
2133         struct smu_baco_context *smu_baco = &smu->smu_baco;
2134         struct amdgpu_device *adev = smu->adev;
2135
2136         if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
2137                 return smu_v13_0_baco_set_armd3_sequence(smu,
2138                                 smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO);
2139         else
2140                 return smu_v13_0_baco_enter(smu);
2141 }
2142
2143 static int smu_v13_0_7_baco_exit(struct smu_context *smu)
2144 {
2145         struct amdgpu_device *adev = smu->adev;
2146
2147         if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
2148                 /* Wait for PMFW handling for the Dstate change */
2149                 usleep_range(10000, 11000);
2150                 return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
2151         } else {
2152                 return smu_v13_0_baco_exit(smu);
2153         }
2154 }
2155
2156 static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu)
2157 {
2158         struct amdgpu_device *adev = smu->adev;
2159
2160         /* SRIOV does not support SMU mode1 reset */
2161         if (amdgpu_sriov_vf(adev))
2162                 return false;
2163
2164         return true;
2165 }
2166
2167 static int smu_v13_0_7_set_df_cstate(struct smu_context *smu,
2168                                      enum pp_df_cstate state)
2169 {
2170         return smu_cmn_send_smc_msg_with_param(smu,
2171                                                SMU_MSG_DFCstateControl,
2172                                                state,
2173                                                NULL);
2174 }
2175
2176 static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
2177         .get_allowed_feature_mask = smu_v13_0_7_get_allowed_feature_mask,
2178         .set_default_dpm_table = smu_v13_0_7_set_default_dpm_table,
2179         .is_dpm_running = smu_v13_0_7_is_dpm_running,
2180         .dump_pptable = smu_v13_0_7_dump_pptable,
2181         .init_microcode = smu_v13_0_init_microcode,
2182         .load_microcode = smu_v13_0_load_microcode,
2183         .fini_microcode = smu_v13_0_fini_microcode,
2184         .init_smc_tables = smu_v13_0_7_init_smc_tables,
2185         .fini_smc_tables = smu_v13_0_fini_smc_tables,
2186         .init_power = smu_v13_0_init_power,
2187         .fini_power = smu_v13_0_fini_power,
2188         .check_fw_status = smu_v13_0_7_check_fw_status,
2189         .setup_pptable = smu_v13_0_7_setup_pptable,
2190         .check_fw_version = smu_v13_0_check_fw_version,
2191         .write_pptable = smu_cmn_write_pptable,
2192         .set_driver_table_location = smu_v13_0_set_driver_table_location,
2193         .system_features_control = smu_v13_0_system_features_control,
2194         .set_allowed_mask = smu_v13_0_set_allowed_mask,
2195         .get_enabled_mask = smu_cmn_get_enabled_mask,
2196         .dpm_set_vcn_enable = smu_v13_0_set_vcn_enable,
2197         .dpm_set_jpeg_enable = smu_v13_0_set_jpeg_enable,
2198         .init_pptable_microcode = smu_v13_0_init_pptable_microcode,
2199         .populate_umd_state_clk = smu_v13_0_7_populate_umd_state_clk,
2200         .get_dpm_ultimate_freq = smu_v13_0_7_get_dpm_ultimate_freq,
2201         .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values,
2202         .read_sensor = smu_v13_0_7_read_sensor,
2203         .feature_is_enabled = smu_cmn_feature_is_enabled,
2204         .print_clk_levels = smu_v13_0_7_print_clk_levels,
2205         .force_clk_levels = smu_v13_0_7_force_clk_levels,
2206         .update_pcie_parameters = smu_v13_0_update_pcie_parameters,
2207         .get_thermal_temperature_range = smu_v13_0_7_get_thermal_temperature_range,
2208         .register_irq_handler = smu_v13_0_register_irq_handler,
2209         .enable_thermal_alert = smu_v13_0_enable_thermal_alert,
2210         .disable_thermal_alert = smu_v13_0_disable_thermal_alert,
2211         .notify_memory_pool_location = smu_v13_0_notify_memory_pool_location,
2212         .get_gpu_metrics = smu_v13_0_7_get_gpu_metrics,
2213         .set_soft_freq_limited_range = smu_v13_0_set_soft_freq_limited_range,
2214         .set_default_od_settings = smu_v13_0_7_set_default_od_settings,
2215         .restore_user_od_settings = smu_v13_0_7_restore_user_od_settings,
2216         .od_edit_dpm_table = smu_v13_0_7_od_edit_dpm_table,
2217         .set_performance_level = smu_v13_0_set_performance_level,
2218         .gfx_off_control = smu_v13_0_gfx_off_control,
2219         .get_fan_speed_pwm = smu_v13_0_7_get_fan_speed_pwm,
2220         .get_fan_speed_rpm = smu_v13_0_7_get_fan_speed_rpm,
2221         .set_fan_speed_pwm = smu_v13_0_set_fan_speed_pwm,
2222         .set_fan_speed_rpm = smu_v13_0_set_fan_speed_rpm,
2223         .get_fan_control_mode = smu_v13_0_get_fan_control_mode,
2224         .set_fan_control_mode = smu_v13_0_set_fan_control_mode,
2225         .enable_mgpu_fan_boost = smu_v13_0_7_enable_mgpu_fan_boost,
2226         .get_power_limit = smu_v13_0_7_get_power_limit,
2227         .set_power_limit = smu_v13_0_set_power_limit,
2228         .set_power_source = smu_v13_0_set_power_source,
2229         .get_power_profile_mode = smu_v13_0_7_get_power_profile_mode,
2230         .set_power_profile_mode = smu_v13_0_7_set_power_profile_mode,
2231         .set_tool_table_location = smu_v13_0_set_tool_table_location,
2232         .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
2233         .set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
2234         .baco_is_support = smu_v13_0_baco_is_support,
2235         .baco_get_state = smu_v13_0_baco_get_state,
2236         .baco_set_state = smu_v13_0_baco_set_state,
2237         .baco_enter = smu_v13_0_7_baco_enter,
2238         .baco_exit = smu_v13_0_7_baco_exit,
2239         .mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported,
2240         .mode1_reset = smu_v13_0_mode1_reset,
2241         .set_mp1_state = smu_v13_0_7_set_mp1_state,
2242         .set_df_cstate = smu_v13_0_7_set_df_cstate,
2243         .gpo_control = smu_v13_0_gpo_control,
2244 };
2245
2246 void smu_v13_0_7_set_ppt_funcs(struct smu_context *smu)
2247 {
2248         smu->ppt_funcs = &smu_v13_0_7_ppt_funcs;
2249         smu->message_map = smu_v13_0_7_message_map;
2250         smu->clock_map = smu_v13_0_7_clk_map;
2251         smu->feature_map = smu_v13_0_7_feature_mask_map;
2252         smu->table_map = smu_v13_0_7_table_map;
2253         smu->pwr_src_map = smu_v13_0_7_pwr_src_map;
2254         smu->workload_map = smu_v13_0_7_workload_map;
2255         smu->smc_driver_if_version = SMU13_0_7_DRIVER_IF_VERSION;
2256         smu_v13_0_set_smu_mailbox_registers(smu);
2257 }