Merge branch 'for-next' into for-linus
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / pm / swsmu / smu11 / sienna_cichlid_ppt.c
1 /*
2  * Copyright 2019 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23
24 #define SWSMU_CODE_LAYER_L2
25
26 #include <linux/firmware.h>
27 #include <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_v11_0.h"
35 #include "smu11_driver_if_sienna_cichlid.h"
36 #include "soc15_common.h"
37 #include "atom.h"
38 #include "sienna_cichlid_ppt.h"
39 #include "smu_v11_0_7_pptable.h"
40 #include "smu_v11_0_7_ppsmc.h"
41 #include "nbio/nbio_2_3_offset.h"
42 #include "nbio/nbio_2_3_sh_mask.h"
43 #include "thm/thm_11_0_2_offset.h"
44 #include "thm/thm_11_0_2_sh_mask.h"
45 #include "mp/mp_11_0_offset.h"
46 #include "mp/mp_11_0_sh_mask.h"
47
48 #include "asic_reg/mp/mp_11_0_sh_mask.h"
49 #include "smu_cmn.h"
50
51 /*
52  * DO NOT use these for err/warn/info/debug messages.
53  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
54  * They are more MGPU friendly.
55  */
56 #undef pr_err
57 #undef pr_warn
58 #undef pr_info
59 #undef pr_debug
60
61 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
62
63 #define FEATURE_MASK(feature) (1ULL << feature)
64 #define SMC_DPM_FEATURE ( \
65         FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) | \
66         FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT)     | \
67         FEATURE_MASK(FEATURE_DPM_UCLK_BIT)       | \
68         FEATURE_MASK(FEATURE_DPM_LINK_BIT)       | \
69         FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT)     | \
70         FEATURE_MASK(FEATURE_DPM_FCLK_BIT)       | \
71         FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)    | \
72         FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT))
73
74 #define SMU_11_0_7_GFX_BUSY_THRESHOLD 15
75
76 static struct cmn2asic_msg_mapping sienna_cichlid_message_map[SMU_MSG_MAX_COUNT] = {
77         MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage,                 1),
78         MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetSmuVersion,               1),
79         MSG_MAP(GetDriverIfVersion,             PPSMC_MSG_GetDriverIfVersion,          1),
80         MSG_MAP(SetAllowedFeaturesMaskLow,      PPSMC_MSG_SetAllowedFeaturesMaskLow,   0),
81         MSG_MAP(SetAllowedFeaturesMaskHigh,     PPSMC_MSG_SetAllowedFeaturesMaskHigh,  0),
82         MSG_MAP(EnableAllSmuFeatures,           PPSMC_MSG_EnableAllSmuFeatures,        0),
83         MSG_MAP(DisableAllSmuFeatures,          PPSMC_MSG_DisableAllSmuFeatures,       0),
84         MSG_MAP(EnableSmuFeaturesLow,           PPSMC_MSG_EnableSmuFeaturesLow,        1),
85         MSG_MAP(EnableSmuFeaturesHigh,          PPSMC_MSG_EnableSmuFeaturesHigh,       1),
86         MSG_MAP(DisableSmuFeaturesLow,          PPSMC_MSG_DisableSmuFeaturesLow,       1),
87         MSG_MAP(DisableSmuFeaturesHigh,         PPSMC_MSG_DisableSmuFeaturesHigh,      1),
88         MSG_MAP(GetEnabledSmuFeaturesLow,       PPSMC_MSG_GetRunningSmuFeaturesLow,    1),
89         MSG_MAP(GetEnabledSmuFeaturesHigh,      PPSMC_MSG_GetRunningSmuFeaturesHigh,   1),
90         MSG_MAP(SetWorkloadMask,                PPSMC_MSG_SetWorkloadMask,             1),
91         MSG_MAP(SetPptLimit,                    PPSMC_MSG_SetPptLimit,                 0),
92         MSG_MAP(SetDriverDramAddrHigh,          PPSMC_MSG_SetDriverDramAddrHigh,       1),
93         MSG_MAP(SetDriverDramAddrLow,           PPSMC_MSG_SetDriverDramAddrLow,        1),
94         MSG_MAP(SetToolsDramAddrHigh,           PPSMC_MSG_SetToolsDramAddrHigh,        0),
95         MSG_MAP(SetToolsDramAddrLow,            PPSMC_MSG_SetToolsDramAddrLow,         0),
96         MSG_MAP(TransferTableSmu2Dram,          PPSMC_MSG_TransferTableSmu2Dram,       1),
97         MSG_MAP(TransferTableDram2Smu,          PPSMC_MSG_TransferTableDram2Smu,       0),
98         MSG_MAP(UseDefaultPPTable,              PPSMC_MSG_UseDefaultPPTable,           0),
99         MSG_MAP(RunDcBtc,                       PPSMC_MSG_RunDcBtc,                    0),
100         MSG_MAP(EnterBaco,                      PPSMC_MSG_EnterBaco,                   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(SetGeminiMode,                  PPSMC_MSG_SetGeminiMode,               0),
109         MSG_MAP(SetGeminiApertureHigh,          PPSMC_MSG_SetGeminiApertureHigh,       0),
110         MSG_MAP(SetGeminiApertureLow,           PPSMC_MSG_SetGeminiApertureLow,        0),
111         MSG_MAP(OverridePcieParameters,         PPSMC_MSG_OverridePcieParameters,      0),
112         MSG_MAP(ReenableAcDcInterrupt,          PPSMC_MSG_ReenableAcDcInterrupt,       0),
113         MSG_MAP(NotifyPowerSource,              PPSMC_MSG_NotifyPowerSource,           0),
114         MSG_MAP(SetUclkFastSwitch,              PPSMC_MSG_SetUclkFastSwitch,           0),
115         MSG_MAP(SetVideoFps,                    PPSMC_MSG_SetVideoFps,                 0),
116         MSG_MAP(PrepareMp1ForUnload,            PPSMC_MSG_PrepareMp1ForUnload,         1),
117         MSG_MAP(AllowGfxOff,                    PPSMC_MSG_AllowGfxOff,                 0),
118         MSG_MAP(DisallowGfxOff,                 PPSMC_MSG_DisallowGfxOff,              0),
119         MSG_MAP(GetPptLimit,                    PPSMC_MSG_GetPptLimit,                 0),
120         MSG_MAP(GetDcModeMaxDpmFreq,            PPSMC_MSG_GetDcModeMaxDpmFreq,         1),
121         MSG_MAP(ExitBaco,                       PPSMC_MSG_ExitBaco,                    0),
122         MSG_MAP(PowerUpVcn,                     PPSMC_MSG_PowerUpVcn,                  0),
123         MSG_MAP(PowerDownVcn,                   PPSMC_MSG_PowerDownVcn,                0),
124         MSG_MAP(PowerUpJpeg,                    PPSMC_MSG_PowerUpJpeg,                 0),
125         MSG_MAP(PowerDownJpeg,                  PPSMC_MSG_PowerDownJpeg,               0),
126         MSG_MAP(BacoAudioD3PME,                 PPSMC_MSG_BacoAudioD3PME,              0),
127         MSG_MAP(ArmD3,                          PPSMC_MSG_ArmD3,                       0),
128         MSG_MAP(Mode1Reset,                     PPSMC_MSG_Mode1Reset,                  0),
129         MSG_MAP(SetMGpuFanBoostLimitRpm,        PPSMC_MSG_SetMGpuFanBoostLimitRpm,     0),
130         MSG_MAP(SetGpoFeaturePMask,             PPSMC_MSG_SetGpoFeaturePMask,          0),
131         MSG_MAP(DisallowGpo,                    PPSMC_MSG_DisallowGpo,                 0),
132         MSG_MAP(Enable2ndUSB20Port,             PPSMC_MSG_Enable2ndUSB20Port,          0),
133 };
134
135 static struct cmn2asic_mapping sienna_cichlid_clk_map[SMU_CLK_COUNT] = {
136         CLK_MAP(GFXCLK,         PPCLK_GFXCLK),
137         CLK_MAP(SCLK,           PPCLK_GFXCLK),
138         CLK_MAP(SOCCLK,         PPCLK_SOCCLK),
139         CLK_MAP(FCLK,           PPCLK_FCLK),
140         CLK_MAP(UCLK,           PPCLK_UCLK),
141         CLK_MAP(MCLK,           PPCLK_UCLK),
142         CLK_MAP(DCLK,           PPCLK_DCLK_0),
143         CLK_MAP(DCLK1,          PPCLK_DCLK_1),
144         CLK_MAP(VCLK,           PPCLK_VCLK_0),
145         CLK_MAP(VCLK1,          PPCLK_VCLK_1),
146         CLK_MAP(DCEFCLK,        PPCLK_DCEFCLK),
147         CLK_MAP(DISPCLK,        PPCLK_DISPCLK),
148         CLK_MAP(PIXCLK,         PPCLK_PIXCLK),
149         CLK_MAP(PHYCLK,         PPCLK_PHYCLK),
150 };
151
152 static struct cmn2asic_mapping sienna_cichlid_feature_mask_map[SMU_FEATURE_COUNT] = {
153         FEA_MAP(DPM_PREFETCHER),
154         FEA_MAP(DPM_GFXCLK),
155         FEA_MAP(DPM_GFX_GPO),
156         FEA_MAP(DPM_UCLK),
157         FEA_MAP(DPM_FCLK),
158         FEA_MAP(DPM_SOCCLK),
159         FEA_MAP(DPM_MP0CLK),
160         FEA_MAP(DPM_LINK),
161         FEA_MAP(DPM_DCEFCLK),
162         FEA_MAP(DPM_XGMI),
163         FEA_MAP(MEM_VDDCI_SCALING),
164         FEA_MAP(MEM_MVDD_SCALING),
165         FEA_MAP(DS_GFXCLK),
166         FEA_MAP(DS_SOCCLK),
167         FEA_MAP(DS_FCLK),
168         FEA_MAP(DS_LCLK),
169         FEA_MAP(DS_DCEFCLK),
170         FEA_MAP(DS_UCLK),
171         FEA_MAP(GFX_ULV),
172         FEA_MAP(FW_DSTATE),
173         FEA_MAP(GFXOFF),
174         FEA_MAP(BACO),
175         FEA_MAP(MM_DPM_PG),
176         FEA_MAP(RSMU_SMN_CG),
177         FEA_MAP(PPT),
178         FEA_MAP(TDC),
179         FEA_MAP(APCC_PLUS),
180         FEA_MAP(GTHR),
181         FEA_MAP(ACDC),
182         FEA_MAP(VR0HOT),
183         FEA_MAP(VR1HOT),
184         FEA_MAP(FW_CTF),
185         FEA_MAP(FAN_CONTROL),
186         FEA_MAP(THERMAL),
187         FEA_MAP(GFX_DCS),
188         FEA_MAP(RM),
189         FEA_MAP(LED_DISPLAY),
190         FEA_MAP(GFX_SS),
191         FEA_MAP(OUT_OF_BAND_MONITOR),
192         FEA_MAP(TEMP_DEPENDENT_VMIN),
193         FEA_MAP(MMHUB_PG),
194         FEA_MAP(ATHUB_PG),
195         FEA_MAP(APCC_DFLL),
196 };
197
198 static struct cmn2asic_mapping sienna_cichlid_table_map[SMU_TABLE_COUNT] = {
199         TAB_MAP(PPTABLE),
200         TAB_MAP(WATERMARKS),
201         TAB_MAP(AVFS_PSM_DEBUG),
202         TAB_MAP(AVFS_FUSE_OVERRIDE),
203         TAB_MAP(PMSTATUSLOG),
204         TAB_MAP(SMU_METRICS),
205         TAB_MAP(DRIVER_SMU_CONFIG),
206         TAB_MAP(ACTIVITY_MONITOR_COEFF),
207         TAB_MAP(OVERDRIVE),
208         TAB_MAP(I2C_COMMANDS),
209         TAB_MAP(PACE),
210 };
211
212 static struct cmn2asic_mapping sienna_cichlid_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
213         PWR_MAP(AC),
214         PWR_MAP(DC),
215 };
216
217 static struct cmn2asic_mapping sienna_cichlid_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 };
226
227 static int
228 sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu,
229                                   uint32_t *feature_mask, uint32_t num)
230 {
231         struct amdgpu_device *adev = smu->adev;
232
233         if (num > 2)
234                 return -EINVAL;
235
236         memset(feature_mask, 0, sizeof(uint32_t) * num);
237
238         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT)
239                                 | FEATURE_MASK(FEATURE_DPM_FCLK_BIT)
240                                 | FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)
241                                 | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT)
242                                 | FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT)
243                                 | FEATURE_MASK(FEATURE_DS_FCLK_BIT)
244                                 | FEATURE_MASK(FEATURE_DS_UCLK_BIT)
245                                 | FEATURE_MASK(FEATURE_FW_DSTATE_BIT)
246                                 | FEATURE_MASK(FEATURE_DF_CSTATE_BIT)
247                                 | FEATURE_MASK(FEATURE_RSMU_SMN_CG_BIT)
248                                 | FEATURE_MASK(FEATURE_GFX_SS_BIT)
249                                 | FEATURE_MASK(FEATURE_VR0HOT_BIT)
250                                 | FEATURE_MASK(FEATURE_PPT_BIT)
251                                 | FEATURE_MASK(FEATURE_TDC_BIT)
252                                 | FEATURE_MASK(FEATURE_BACO_BIT)
253                                 | FEATURE_MASK(FEATURE_APCC_DFLL_BIT)
254                                 | FEATURE_MASK(FEATURE_FW_CTF_BIT)
255                                 | FEATURE_MASK(FEATURE_FAN_CONTROL_BIT)
256                                 | FEATURE_MASK(FEATURE_THERMAL_BIT)
257                                 | FEATURE_MASK(FEATURE_OUT_OF_BAND_MONITOR_BIT);
258
259         if (adev->pm.pp_feature & PP_SCLK_DPM_MASK) {
260                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT);
261                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFX_GPO_BIT);
262         }
263
264         if ((adev->pm.pp_feature & PP_GFX_DCS_MASK) &&
265             (adev->asic_type > CHIP_SIENNA_CICHLID) &&
266             !(adev->flags & AMD_IS_APU))
267                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_DCS_BIT);
268
269         if (adev->pm.pp_feature & PP_MCLK_DPM_MASK)
270                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT)
271                                         | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT)
272                                         | FEATURE_MASK(FEATURE_MEM_MVDD_SCALING_BIT);
273
274         if (adev->pm.pp_feature & PP_PCIE_DPM_MASK)
275                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_LINK_BIT);
276
277         if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK)
278                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT);
279
280         if (adev->pm.pp_feature & PP_SOCCLK_DPM_MASK)
281                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT);
282
283         if (adev->pm.pp_feature & PP_ULV_MASK)
284                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_ULV_BIT);
285
286         if (adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK)
287                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_GFXCLK_BIT);
288
289         if (adev->pm.pp_feature & PP_GFXOFF_MASK)
290                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXOFF_BIT);
291
292         if (smu->adev->pg_flags & AMD_PG_SUPPORT_ATHUB)
293                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ATHUB_PG_BIT);
294
295         if (smu->adev->pg_flags & AMD_PG_SUPPORT_MMHUB)
296                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MMHUB_PG_BIT);
297
298         if (smu->adev->pg_flags & AMD_PG_SUPPORT_VCN ||
299             smu->adev->pg_flags & AMD_PG_SUPPORT_JPEG)
300                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MM_DPM_PG_BIT);
301
302         if (smu->dc_controlled_by_gpio)
303        *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ACDC_BIT);
304
305         if (amdgpu_aspm == 1)
306                 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_LCLK_BIT);
307
308         return 0;
309 }
310
311 static int sienna_cichlid_check_powerplay_table(struct smu_context *smu)
312 {
313         struct smu_table_context *table_context = &smu->smu_table;
314         struct smu_11_0_7_powerplay_table *powerplay_table =
315                 table_context->power_play_table;
316         struct smu_baco_context *smu_baco = &smu->smu_baco;
317
318         if (powerplay_table->platform_caps & SMU_11_0_7_PP_PLATFORM_CAP_HARDWAREDC)
319                 smu->dc_controlled_by_gpio = true;
320
321         if (powerplay_table->platform_caps & SMU_11_0_7_PP_PLATFORM_CAP_BACO ||
322             powerplay_table->platform_caps & SMU_11_0_7_PP_PLATFORM_CAP_MACO)
323                 smu_baco->platform_support = true;
324
325         table_context->thermal_controller_type =
326                 powerplay_table->thermal_controller_type;
327
328         /*
329          * Instead of having its own buffer space and get overdrive_table copied,
330          * smu->od_settings just points to the actual overdrive_table
331          */
332         smu->od_settings = &powerplay_table->overdrive_table;
333
334         return 0;
335 }
336
337 static int sienna_cichlid_append_powerplay_table(struct smu_context *smu)
338 {
339         struct smu_table_context *table_context = &smu->smu_table;
340         PPTable_t *smc_pptable = table_context->driver_pptable;
341         struct atom_smc_dpm_info_v4_9 *smc_dpm_table;
342         int index, ret;
343
344         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
345                                             smc_dpm_info);
346
347         ret = amdgpu_atombios_get_data_table(smu->adev, index, NULL, NULL, NULL,
348                                       (uint8_t **)&smc_dpm_table);
349         if (ret)
350                 return ret;
351
352         memcpy(smc_pptable->I2cControllers, smc_dpm_table->I2cControllers,
353                sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header));
354         
355         return 0;
356 }
357
358 static int sienna_cichlid_store_powerplay_table(struct smu_context *smu)
359 {
360         struct smu_table_context *table_context = &smu->smu_table;
361         struct smu_11_0_7_powerplay_table *powerplay_table =
362                 table_context->power_play_table;
363
364         memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
365                sizeof(PPTable_t));
366
367         return 0;
368 }
369
370 static int sienna_cichlid_setup_pptable(struct smu_context *smu)
371 {
372         int ret = 0;
373
374         ret = smu_v11_0_setup_pptable(smu);
375         if (ret)
376                 return ret;
377
378         ret = sienna_cichlid_store_powerplay_table(smu);
379         if (ret)
380                 return ret;
381
382         ret = sienna_cichlid_append_powerplay_table(smu);
383         if (ret)
384                 return ret;
385
386         ret = sienna_cichlid_check_powerplay_table(smu);
387         if (ret)
388                 return ret;
389
390         return ret;
391 }
392
393 static int sienna_cichlid_tables_init(struct smu_context *smu)
394 {
395         struct smu_table_context *smu_table = &smu->smu_table;
396         struct smu_table *tables = smu_table->tables;
397
398         SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
399                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
400         SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
401                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
402         SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetricsExternal_t),
403                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
404         SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
405                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
406         SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTable_t),
407                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
408         SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE,
409                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
410         SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF,
411                        sizeof(DpmActivityMonitorCoeffIntExternal_t), PAGE_SIZE,
412                        AMDGPU_GEM_DOMAIN_VRAM);
413
414         smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), GFP_KERNEL);
415         if (!smu_table->metrics_table)
416                 goto err0_out;
417         smu_table->metrics_time = 0;
418
419         smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_1);
420         smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
421         if (!smu_table->gpu_metrics_table)
422                 goto err1_out;
423
424         smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
425         if (!smu_table->watermarks_table)
426                 goto err2_out;
427
428         return 0;
429
430 err2_out:
431         kfree(smu_table->gpu_metrics_table);
432 err1_out:
433         kfree(smu_table->metrics_table);
434 err0_out:
435         return -ENOMEM;
436 }
437
438 static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu,
439                                                MetricsMember_t member,
440                                                uint32_t *value)
441 {
442         struct smu_table_context *smu_table= &smu->smu_table;
443         SmuMetrics_t *metrics =
444                 &(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics);
445         int ret = 0;
446
447         mutex_lock(&smu->metrics_lock);
448
449         ret = smu_cmn_get_metrics_table_locked(smu,
450                                                NULL,
451                                                false);
452         if (ret) {
453                 mutex_unlock(&smu->metrics_lock);
454                 return ret;
455         }
456
457         switch (member) {
458         case METRICS_CURR_GFXCLK:
459                 *value = metrics->CurrClock[PPCLK_GFXCLK];
460                 break;
461         case METRICS_CURR_SOCCLK:
462                 *value = metrics->CurrClock[PPCLK_SOCCLK];
463                 break;
464         case METRICS_CURR_UCLK:
465                 *value = metrics->CurrClock[PPCLK_UCLK];
466                 break;
467         case METRICS_CURR_VCLK:
468                 *value = metrics->CurrClock[PPCLK_VCLK_0];
469                 break;
470         case METRICS_CURR_VCLK1:
471                 *value = metrics->CurrClock[PPCLK_VCLK_1];
472                 break;
473         case METRICS_CURR_DCLK:
474                 *value = metrics->CurrClock[PPCLK_DCLK_0];
475                 break;
476         case METRICS_CURR_DCLK1:
477                 *value = metrics->CurrClock[PPCLK_DCLK_1];
478                 break;
479         case METRICS_CURR_DCEFCLK:
480                 *value = metrics->CurrClock[PPCLK_DCEFCLK];
481                 break;
482         case METRICS_CURR_FCLK:
483                 *value = metrics->CurrClock[PPCLK_FCLK];
484                 break;
485         case METRICS_AVERAGE_GFXCLK:
486                 if (metrics->AverageGfxActivity <= SMU_11_0_7_GFX_BUSY_THRESHOLD)
487                         *value = metrics->AverageGfxclkFrequencyPostDs;
488                 else
489                         *value = metrics->AverageGfxclkFrequencyPreDs;
490                 break;
491         case METRICS_AVERAGE_FCLK:
492                 *value = metrics->AverageFclkFrequencyPostDs;
493                 break;
494         case METRICS_AVERAGE_UCLK:
495                 *value = metrics->AverageUclkFrequencyPostDs;
496                 break;
497         case METRICS_AVERAGE_GFXACTIVITY:
498                 *value = metrics->AverageGfxActivity;
499                 break;
500         case METRICS_AVERAGE_MEMACTIVITY:
501                 *value = metrics->AverageUclkActivity;
502                 break;
503         case METRICS_AVERAGE_SOCKETPOWER:
504                 *value = metrics->AverageSocketPower << 8;
505                 break;
506         case METRICS_TEMPERATURE_EDGE:
507                 *value = metrics->TemperatureEdge *
508                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
509                 break;
510         case METRICS_TEMPERATURE_HOTSPOT:
511                 *value = metrics->TemperatureHotspot *
512                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
513                 break;
514         case METRICS_TEMPERATURE_MEM:
515                 *value = metrics->TemperatureMem *
516                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
517                 break;
518         case METRICS_TEMPERATURE_VRGFX:
519                 *value = metrics->TemperatureVrGfx *
520                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
521                 break;
522         case METRICS_TEMPERATURE_VRSOC:
523                 *value = metrics->TemperatureVrSoc *
524                         SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
525                 break;
526         case METRICS_THROTTLER_STATUS:
527                 *value = metrics->ThrottlerStatus;
528                 break;
529         case METRICS_CURR_FANSPEED:
530                 *value = metrics->CurrFanSpeed;
531                 break;
532         default:
533                 *value = UINT_MAX;
534                 break;
535         }
536
537         mutex_unlock(&smu->metrics_lock);
538
539         return ret;
540
541 }
542
543 static int sienna_cichlid_allocate_dpm_context(struct smu_context *smu)
544 {
545         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
546
547         smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context),
548                                        GFP_KERNEL);
549         if (!smu_dpm->dpm_context)
550                 return -ENOMEM;
551
552         smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context);
553
554         return 0;
555 }
556
557 static int sienna_cichlid_init_smc_tables(struct smu_context *smu)
558 {
559         int ret = 0;
560
561         ret = sienna_cichlid_tables_init(smu);
562         if (ret)
563                 return ret;
564
565         ret = sienna_cichlid_allocate_dpm_context(smu);
566         if (ret)
567                 return ret;
568
569         return smu_v11_0_init_smc_tables(smu);
570 }
571
572 static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu)
573 {
574         struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
575         PPTable_t *driver_ppt = smu->smu_table.driver_pptable;
576         struct smu_11_0_dpm_table *dpm_table;
577         struct amdgpu_device *adev = smu->adev;
578         int ret = 0;
579
580         /* socclk dpm table setup */
581         dpm_table = &dpm_context->dpm_tables.soc_table;
582         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
583                 ret = smu_v11_0_set_single_dpm_table(smu,
584                                                      SMU_SOCCLK,
585                                                      dpm_table);
586                 if (ret)
587                         return ret;
588                 dpm_table->is_fine_grained =
589                         !driver_ppt->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete;
590         } else {
591                 dpm_table->count = 1;
592                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
593                 dpm_table->dpm_levels[0].enabled = true;
594                 dpm_table->min = dpm_table->dpm_levels[0].value;
595                 dpm_table->max = dpm_table->dpm_levels[0].value;
596         }
597
598         /* gfxclk dpm table setup */
599         dpm_table = &dpm_context->dpm_tables.gfx_table;
600         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
601                 ret = smu_v11_0_set_single_dpm_table(smu,
602                                                      SMU_GFXCLK,
603                                                      dpm_table);
604                 if (ret)
605                         return ret;
606                 dpm_table->is_fine_grained =
607                         !driver_ppt->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete;
608         } else {
609                 dpm_table->count = 1;
610                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
611                 dpm_table->dpm_levels[0].enabled = true;
612                 dpm_table->min = dpm_table->dpm_levels[0].value;
613                 dpm_table->max = dpm_table->dpm_levels[0].value;
614         }
615
616         /* uclk dpm table setup */
617         dpm_table = &dpm_context->dpm_tables.uclk_table;
618         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
619                 ret = smu_v11_0_set_single_dpm_table(smu,
620                                                      SMU_UCLK,
621                                                      dpm_table);
622                 if (ret)
623                         return ret;
624                 dpm_table->is_fine_grained =
625                         !driver_ppt->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete;
626         } else {
627                 dpm_table->count = 1;
628                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
629                 dpm_table->dpm_levels[0].enabled = true;
630                 dpm_table->min = dpm_table->dpm_levels[0].value;
631                 dpm_table->max = dpm_table->dpm_levels[0].value;
632         }
633
634         /* fclk dpm table setup */
635         dpm_table = &dpm_context->dpm_tables.fclk_table;
636         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
637                 ret = smu_v11_0_set_single_dpm_table(smu,
638                                                      SMU_FCLK,
639                                                      dpm_table);
640                 if (ret)
641                         return ret;
642                 dpm_table->is_fine_grained =
643                         !driver_ppt->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete;
644         } else {
645                 dpm_table->count = 1;
646                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.fclk / 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         /* vclk0 dpm table setup */
653         dpm_table = &dpm_context->dpm_tables.vclk_table;
654         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
655                 ret = smu_v11_0_set_single_dpm_table(smu,
656                                                      SMU_VCLK,
657                                                      dpm_table);
658                 if (ret)
659                         return ret;
660                 dpm_table->is_fine_grained =
661                         !driver_ppt->DpmDescriptor[PPCLK_VCLK_0].SnapToDiscrete;
662         } else {
663                 dpm_table->count = 1;
664                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100;
665                 dpm_table->dpm_levels[0].enabled = true;
666                 dpm_table->min = dpm_table->dpm_levels[0].value;
667                 dpm_table->max = dpm_table->dpm_levels[0].value;
668         }
669
670         /* vclk1 dpm table setup */
671         if (adev->vcn.num_vcn_inst > 1) {
672                 dpm_table = &dpm_context->dpm_tables.vclk1_table;
673                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
674                         ret = smu_v11_0_set_single_dpm_table(smu,
675                                                              SMU_VCLK1,
676                                                              dpm_table);
677                         if (ret)
678                                 return ret;
679                         dpm_table->is_fine_grained =
680                                 !driver_ppt->DpmDescriptor[PPCLK_VCLK_1].SnapToDiscrete;
681                 } else {
682                         dpm_table->count = 1;
683                         dpm_table->dpm_levels[0].value =
684                                 smu->smu_table.boot_values.vclk / 100;
685                         dpm_table->dpm_levels[0].enabled = true;
686                         dpm_table->min = dpm_table->dpm_levels[0].value;
687                         dpm_table->max = dpm_table->dpm_levels[0].value;
688                 }
689         }
690
691         /* dclk0 dpm table setup */
692         dpm_table = &dpm_context->dpm_tables.dclk_table;
693         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
694                 ret = smu_v11_0_set_single_dpm_table(smu,
695                                                      SMU_DCLK,
696                                                      dpm_table);
697                 if (ret)
698                         return ret;
699                 dpm_table->is_fine_grained =
700                         !driver_ppt->DpmDescriptor[PPCLK_DCLK_0].SnapToDiscrete;
701         } else {
702                 dpm_table->count = 1;
703                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100;
704                 dpm_table->dpm_levels[0].enabled = true;
705                 dpm_table->min = dpm_table->dpm_levels[0].value;
706                 dpm_table->max = dpm_table->dpm_levels[0].value;
707         }
708
709         /* dclk1 dpm table setup */
710         if (adev->vcn.num_vcn_inst > 1) {
711                 dpm_table = &dpm_context->dpm_tables.dclk1_table;
712                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
713                         ret = smu_v11_0_set_single_dpm_table(smu,
714                                                              SMU_DCLK1,
715                                                              dpm_table);
716                         if (ret)
717                                 return ret;
718                         dpm_table->is_fine_grained =
719                                 !driver_ppt->DpmDescriptor[PPCLK_DCLK_1].SnapToDiscrete;
720                 } else {
721                         dpm_table->count = 1;
722                         dpm_table->dpm_levels[0].value =
723                                 smu->smu_table.boot_values.dclk / 100;
724                         dpm_table->dpm_levels[0].enabled = true;
725                         dpm_table->min = dpm_table->dpm_levels[0].value;
726                         dpm_table->max = dpm_table->dpm_levels[0].value;
727                 }
728         }
729
730         /* dcefclk dpm table setup */
731         dpm_table = &dpm_context->dpm_tables.dcef_table;
732         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
733                 ret = smu_v11_0_set_single_dpm_table(smu,
734                                                      SMU_DCEFCLK,
735                                                      dpm_table);
736                 if (ret)
737                         return ret;
738                 dpm_table->is_fine_grained =
739                         !driver_ppt->DpmDescriptor[PPCLK_DCEFCLK].SnapToDiscrete;
740         } else {
741                 dpm_table->count = 1;
742                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
743                 dpm_table->dpm_levels[0].enabled = true;
744                 dpm_table->min = dpm_table->dpm_levels[0].value;
745                 dpm_table->max = dpm_table->dpm_levels[0].value;
746         }
747
748         /* pixelclk dpm table setup */
749         dpm_table = &dpm_context->dpm_tables.pixel_table;
750         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
751                 ret = smu_v11_0_set_single_dpm_table(smu,
752                                                      SMU_PIXCLK,
753                                                      dpm_table);
754                 if (ret)
755                         return ret;
756                 dpm_table->is_fine_grained =
757                         !driver_ppt->DpmDescriptor[PPCLK_PIXCLK].SnapToDiscrete;
758         } else {
759                 dpm_table->count = 1;
760                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
761                 dpm_table->dpm_levels[0].enabled = true;
762                 dpm_table->min = dpm_table->dpm_levels[0].value;
763                 dpm_table->max = dpm_table->dpm_levels[0].value;
764         }
765
766         /* displayclk dpm table setup */
767         dpm_table = &dpm_context->dpm_tables.display_table;
768         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
769                 ret = smu_v11_0_set_single_dpm_table(smu,
770                                                      SMU_DISPCLK,
771                                                      dpm_table);
772                 if (ret)
773                         return ret;
774                 dpm_table->is_fine_grained =
775                         !driver_ppt->DpmDescriptor[PPCLK_DISPCLK].SnapToDiscrete;
776         } else {
777                 dpm_table->count = 1;
778                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
779                 dpm_table->dpm_levels[0].enabled = true;
780                 dpm_table->min = dpm_table->dpm_levels[0].value;
781                 dpm_table->max = dpm_table->dpm_levels[0].value;
782         }
783
784         /* phyclk dpm table setup */
785         dpm_table = &dpm_context->dpm_tables.phy_table;
786         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
787                 ret = smu_v11_0_set_single_dpm_table(smu,
788                                                      SMU_PHYCLK,
789                                                      dpm_table);
790                 if (ret)
791                         return ret;
792                 dpm_table->is_fine_grained =
793                         !driver_ppt->DpmDescriptor[PPCLK_PHYCLK].SnapToDiscrete;
794         } else {
795                 dpm_table->count = 1;
796                 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
797                 dpm_table->dpm_levels[0].enabled = true;
798                 dpm_table->min = dpm_table->dpm_levels[0].value;
799                 dpm_table->max = dpm_table->dpm_levels[0].value;
800         }
801
802         return 0;
803 }
804
805 static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
806 {
807         struct amdgpu_device *adev = smu->adev;
808         int ret = 0;
809
810         if (enable) {
811                 /* vcn dpm on is a prerequisite for vcn power gate messages */
812                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
813                         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL);
814                         if (ret)
815                                 return ret;
816                         if (adev->vcn.num_vcn_inst > 1) {
817                                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn,
818                                                                   0x10000, NULL);
819                                 if (ret)
820                                         return ret;
821                         }
822                 }
823         } else {
824                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
825                         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL);
826                         if (ret)
827                                 return ret;
828                         if (adev->vcn.num_vcn_inst > 1) {
829                                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn,
830                                                                   0x10000, NULL);
831                                 if (ret)
832                                         return ret;
833                         }
834                 }
835         }
836
837         return ret;
838 }
839
840 static int sienna_cichlid_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
841 {
842         int ret = 0;
843
844         if (enable) {
845                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
846                         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpJpeg, 0, NULL);
847                         if (ret)
848                                 return ret;
849                 }
850         } else {
851                 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
852                         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL);
853                         if (ret)
854                                 return ret;
855                 }
856         }
857
858         return ret;
859 }
860
861 static int sienna_cichlid_get_current_clk_freq_by_table(struct smu_context *smu,
862                                        enum smu_clk_type clk_type,
863                                        uint32_t *value)
864 {
865         MetricsMember_t member_type;
866         int clk_id = 0;
867
868         clk_id = smu_cmn_to_asic_specific_index(smu,
869                                                 CMN2ASIC_MAPPING_CLK,
870                                                 clk_type);
871         if (clk_id < 0)
872                 return clk_id;
873
874         switch (clk_id) {
875         case PPCLK_GFXCLK:
876                 member_type = METRICS_CURR_GFXCLK;
877                 break;
878         case PPCLK_UCLK:
879                 member_type = METRICS_CURR_UCLK;
880                 break;
881         case PPCLK_SOCCLK:
882                 member_type = METRICS_CURR_SOCCLK;
883                 break;
884         case PPCLK_FCLK:
885                 member_type = METRICS_CURR_FCLK;
886                 break;
887         case PPCLK_VCLK_0:
888                 member_type = METRICS_CURR_VCLK;
889                 break;
890         case PPCLK_VCLK_1:
891                 member_type = METRICS_CURR_VCLK1;
892                 break;
893         case PPCLK_DCLK_0:
894                 member_type = METRICS_CURR_DCLK;
895                 break;
896         case PPCLK_DCLK_1:
897                 member_type = METRICS_CURR_DCLK1;
898                 break;
899         case PPCLK_DCEFCLK:
900                 member_type = METRICS_CURR_DCEFCLK;
901                 break;
902         default:
903                 return -EINVAL;
904         }
905
906         return sienna_cichlid_get_smu_metrics_data(smu,
907                                                    member_type,
908                                                    value);
909
910 }
911
912 static bool sienna_cichlid_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type)
913 {
914         PPTable_t *pptable = smu->smu_table.driver_pptable;
915         DpmDescriptor_t *dpm_desc = NULL;
916         uint32_t clk_index = 0;
917
918         clk_index = smu_cmn_to_asic_specific_index(smu,
919                                                    CMN2ASIC_MAPPING_CLK,
920                                                    clk_type);
921         dpm_desc = &pptable->DpmDescriptor[clk_index];
922
923         /* 0 - Fine grained DPM, 1 - Discrete DPM */
924         return dpm_desc->SnapToDiscrete == 0;
925 }
926
927 static bool sienna_cichlid_is_od_feature_supported(struct smu_11_0_7_overdrive_table *od_table,
928                                                    enum SMU_11_0_7_ODFEATURE_CAP cap)
929 {
930         return od_table->cap[cap];
931 }
932
933 static void sienna_cichlid_get_od_setting_range(struct smu_11_0_7_overdrive_table *od_table,
934                                                 enum SMU_11_0_7_ODSETTING_ID setting,
935                                                 uint32_t *min, uint32_t *max)
936 {
937         if (min)
938                 *min = od_table->min[setting];
939         if (max)
940                 *max = od_table->max[setting];
941 }
942
943 static int sienna_cichlid_print_clk_levels(struct smu_context *smu,
944                         enum smu_clk_type clk_type, char *buf)
945 {
946         struct amdgpu_device *adev = smu->adev;
947         struct smu_table_context *table_context = &smu->smu_table;
948         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
949         struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context;
950         PPTable_t *pptable = (PPTable_t *)table_context->driver_pptable;
951         struct smu_11_0_7_overdrive_table *od_settings = smu->od_settings;
952         OverDriveTable_t *od_table =
953                 (OverDriveTable_t *)table_context->overdrive_table;
954         int i, size = 0, ret = 0;
955         uint32_t cur_value = 0, value = 0, count = 0;
956         uint32_t freq_values[3] = {0};
957         uint32_t mark_index = 0;
958         uint32_t gen_speed, lane_width;
959         uint32_t min_value, max_value;
960         uint32_t smu_version;
961
962         switch (clk_type) {
963         case SMU_GFXCLK:
964         case SMU_SCLK:
965         case SMU_SOCCLK:
966         case SMU_MCLK:
967         case SMU_UCLK:
968         case SMU_FCLK:
969         case SMU_DCEFCLK:
970                 ret = sienna_cichlid_get_current_clk_freq_by_table(smu, clk_type, &cur_value);
971                 if (ret)
972                         goto print_clk_out;
973
974                 /* no need to disable gfxoff when retrieving the current gfxclk */
975                 if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
976                         amdgpu_gfx_off_ctrl(adev, false);
977
978                 ret = smu_v11_0_get_dpm_level_count(smu, clk_type, &count);
979                 if (ret)
980                         goto print_clk_out;
981
982                 if (!sienna_cichlid_is_support_fine_grained_dpm(smu, clk_type)) {
983                         for (i = 0; i < count; i++) {
984                                 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
985                                 if (ret)
986                                         goto print_clk_out;
987
988                                 size += sprintf(buf + size, "%d: %uMhz %s\n", i, value,
989                                                 cur_value == value ? "*" : "");
990                         }
991                 } else {
992                         ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, 0, &freq_values[0]);
993                         if (ret)
994                                 goto print_clk_out;
995                         ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, count - 1, &freq_values[2]);
996                         if (ret)
997                                 goto print_clk_out;
998
999                         freq_values[1] = cur_value;
1000                         mark_index = cur_value == freq_values[0] ? 0 :
1001                                      cur_value == freq_values[2] ? 2 : 1;
1002
1003                         count = 3;
1004                         if (mark_index != 1) {
1005                                 count = 2;
1006                                 freq_values[1] = freq_values[2];
1007                         }
1008
1009                         for (i = 0; i < count; i++) {
1010                                 size += sprintf(buf + size, "%d: %uMhz %s\n", i, freq_values[i],
1011                                                 cur_value  == freq_values[i] ? "*" : "");
1012                         }
1013
1014                 }
1015                 break;
1016         case SMU_PCIE:
1017                 gen_speed = smu_v11_0_get_current_pcie_link_speed_level(smu);
1018                 lane_width = smu_v11_0_get_current_pcie_link_width_level(smu);
1019                 for (i = 0; i < NUM_LINK_LEVELS; i++)
1020                         size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
1021                                         (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," :
1022                                         (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 1) ? "5.0GT/s," :
1023                                         (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 2) ? "8.0GT/s," :
1024                                         (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 3) ? "16.0GT/s," : "",
1025                                         (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 1) ? "x1" :
1026                                         (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 2) ? "x2" :
1027                                         (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 3) ? "x4" :
1028                                         (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 4) ? "x8" :
1029                                         (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 5) ? "x12" :
1030                                         (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 6) ? "x16" : "",
1031                                         pptable->LclkFreq[i],
1032                                         (gen_speed == dpm_context->dpm_tables.pcie_table.pcie_gen[i]) &&
1033                                         (lane_width == dpm_context->dpm_tables.pcie_table.pcie_lane[i]) ?
1034                                         "*" : "");
1035                 break;
1036         case SMU_OD_SCLK:
1037                 if (!smu->od_enabled || !od_table || !od_settings)
1038                         break;
1039
1040                 if (!sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_GFXCLK_LIMITS))
1041                         break;
1042
1043                 size += sprintf(buf + size, "OD_SCLK:\n");
1044                 size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
1045                 break;
1046
1047         case SMU_OD_MCLK:
1048                 if (!smu->od_enabled || !od_table || !od_settings)
1049                         break;
1050
1051                 if (!sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_UCLK_LIMITS))
1052                         break;
1053
1054                 size += sprintf(buf + size, "OD_MCLK:\n");
1055                 size += sprintf(buf + size, "0: %uMhz\n1: %uMHz\n", od_table->UclkFmin, od_table->UclkFmax);
1056                 break;
1057
1058         case SMU_OD_VDDGFX_OFFSET:
1059                 if (!smu->od_enabled || !od_table || !od_settings)
1060                         break;
1061
1062                 /*
1063                  * OD GFX Voltage Offset functionality is supported only by 58.41.0
1064                  * and onwards SMU firmwares.
1065                  */
1066                 smu_cmn_get_smc_version(smu, NULL, &smu_version);
1067                 if ((adev->asic_type == CHIP_SIENNA_CICHLID) &&
1068                      (smu_version < 0x003a2900))
1069                         break;
1070
1071                 size += sprintf(buf + size, "OD_VDDGFX_OFFSET:\n");
1072                 size += sprintf(buf + size, "%dmV\n", od_table->VddGfxOffset);
1073                 break;
1074
1075         case SMU_OD_RANGE:
1076                 if (!smu->od_enabled || !od_table || !od_settings)
1077                         break;
1078
1079                 size = sprintf(buf, "%s:\n", "OD_RANGE");
1080
1081                 if (sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_GFXCLK_LIMITS)) {
1082                         sienna_cichlid_get_od_setting_range(od_settings, SMU_11_0_7_ODSETTING_GFXCLKFMIN,
1083                                                             &min_value, NULL);
1084                         sienna_cichlid_get_od_setting_range(od_settings, SMU_11_0_7_ODSETTING_GFXCLKFMAX,
1085                                                             NULL, &max_value);
1086                         size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n",
1087                                         min_value, max_value);
1088                 }
1089
1090                 if (sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_UCLK_LIMITS)) {
1091                         sienna_cichlid_get_od_setting_range(od_settings, SMU_11_0_7_ODSETTING_UCLKFMIN,
1092                                                             &min_value, NULL);
1093                         sienna_cichlid_get_od_setting_range(od_settings, SMU_11_0_7_ODSETTING_UCLKFMAX,
1094                                                             NULL, &max_value);
1095                         size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
1096                                         min_value, max_value);
1097                 }
1098                 break;
1099
1100         default:
1101                 break;
1102         }
1103
1104 print_clk_out:
1105         if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
1106                 amdgpu_gfx_off_ctrl(adev, true);
1107
1108         return size;
1109 }
1110
1111 static int sienna_cichlid_force_clk_levels(struct smu_context *smu,
1112                                    enum smu_clk_type clk_type, uint32_t mask)
1113 {
1114         struct amdgpu_device *adev = smu->adev;
1115         int ret = 0, size = 0;
1116         uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0;
1117
1118         soft_min_level = mask ? (ffs(mask) - 1) : 0;
1119         soft_max_level = mask ? (fls(mask) - 1) : 0;
1120
1121         if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
1122                 amdgpu_gfx_off_ctrl(adev, false);
1123
1124         switch (clk_type) {
1125         case SMU_GFXCLK:
1126         case SMU_SCLK:
1127         case SMU_SOCCLK:
1128         case SMU_MCLK:
1129         case SMU_UCLK:
1130         case SMU_FCLK:
1131                 /* There is only 2 levels for fine grained DPM */
1132                 if (sienna_cichlid_is_support_fine_grained_dpm(smu, clk_type)) {
1133                         soft_max_level = (soft_max_level >= 1 ? 1 : 0);
1134                         soft_min_level = (soft_min_level >= 1 ? 1 : 0);
1135                 }
1136
1137                 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq);
1138                 if (ret)
1139                         goto forec_level_out;
1140
1141                 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq);
1142                 if (ret)
1143                         goto forec_level_out;
1144
1145                 ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
1146                 if (ret)
1147                         goto forec_level_out;
1148                 break;
1149         case SMU_DCEFCLK:
1150                 dev_info(smu->adev->dev,"Setting DCEFCLK min/max dpm level is not supported!\n");
1151                 break;
1152         default:
1153                 break;
1154         }
1155
1156 forec_level_out:
1157         if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
1158                 amdgpu_gfx_off_ctrl(adev, true);
1159
1160         return size;
1161 }
1162
1163 static int sienna_cichlid_populate_umd_state_clk(struct smu_context *smu)
1164 {
1165         struct smu_11_0_dpm_context *dpm_context =
1166                                 smu->smu_dpm.dpm_context;
1167         struct smu_11_0_dpm_table *gfx_table =
1168                                 &dpm_context->dpm_tables.gfx_table;
1169         struct smu_11_0_dpm_table *mem_table =
1170                                 &dpm_context->dpm_tables.uclk_table;
1171         struct smu_11_0_dpm_table *soc_table =
1172                                 &dpm_context->dpm_tables.soc_table;
1173         struct smu_umd_pstate_table *pstate_table =
1174                                 &smu->pstate_table;
1175
1176         pstate_table->gfxclk_pstate.min = gfx_table->min;
1177         pstate_table->gfxclk_pstate.peak = gfx_table->max;
1178         if (gfx_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK)
1179                 pstate_table->gfxclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK;
1180
1181         pstate_table->uclk_pstate.min = mem_table->min;
1182         pstate_table->uclk_pstate.peak = mem_table->max;
1183         if (mem_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK)
1184                 pstate_table->uclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK;
1185
1186         pstate_table->socclk_pstate.min = soc_table->min;
1187         pstate_table->socclk_pstate.peak = soc_table->max;
1188         if (soc_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK)
1189                 pstate_table->socclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK;
1190
1191         return 0;
1192 }
1193
1194 static int sienna_cichlid_pre_display_config_changed(struct smu_context *smu)
1195 {
1196         int ret = 0;
1197         uint32_t max_freq = 0;
1198
1199         /* Sienna_Cichlid do not support to change display num currently */
1200         return 0;
1201 #if 0
1202         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, 0, NULL);
1203         if (ret)
1204                 return ret;
1205 #endif
1206
1207         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
1208                 ret = smu_v11_0_get_dpm_ultimate_freq(smu, SMU_UCLK, NULL, &max_freq);
1209                 if (ret)
1210                         return ret;
1211                 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, 0, max_freq);
1212                 if (ret)
1213                         return ret;
1214         }
1215
1216         return ret;
1217 }
1218
1219 static int sienna_cichlid_display_config_changed(struct smu_context *smu)
1220 {
1221         int ret = 0;
1222
1223         if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
1224             smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
1225             smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
1226 #if 0
1227                 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays,
1228                                                   smu->display_config->num_display,
1229                                                   NULL);
1230 #endif
1231                 if (ret)
1232                         return ret;
1233         }
1234
1235         return ret;
1236 }
1237
1238 static bool sienna_cichlid_is_dpm_running(struct smu_context *smu)
1239 {
1240         int ret = 0;
1241         uint32_t feature_mask[2];
1242         uint64_t feature_enabled;
1243
1244         ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2);
1245         if (ret)
1246                 return false;
1247
1248         feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0];
1249
1250         return !!(feature_enabled & SMC_DPM_FEATURE);
1251 }
1252
1253 static int sienna_cichlid_get_fan_speed_percent(struct smu_context *smu,
1254                                                 uint32_t *speed)
1255 {
1256         int ret;
1257         u32 rpm;
1258
1259         if (!speed)
1260                 return -EINVAL;
1261
1262         switch (smu_v11_0_get_fan_control_mode(smu)) {
1263         case AMD_FAN_CTRL_AUTO:
1264                 ret = sienna_cichlid_get_smu_metrics_data(smu,
1265                                                           METRICS_CURR_FANSPEED,
1266                                                           &rpm);
1267                 if (!ret && smu->fan_max_rpm)
1268                         *speed = rpm * 100 / smu->fan_max_rpm;
1269                 return ret;
1270         default:
1271                 *speed = smu->user_dpm_profile.fan_speed_percent;
1272                 return 0;
1273         }
1274 }
1275
1276 static int sienna_cichlid_get_fan_parameters(struct smu_context *smu)
1277 {
1278         PPTable_t *pptable = smu->smu_table.driver_pptable;
1279
1280         smu->fan_max_rpm = pptable->FanMaximumRpm;
1281
1282         return 0;
1283 }
1284
1285 static int sienna_cichlid_get_power_profile_mode(struct smu_context *smu, char *buf)
1286 {
1287         DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
1288         DpmActivityMonitorCoeffInt_t *activity_monitor =
1289                 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
1290         uint32_t i, size = 0;
1291         int16_t workload_type = 0;
1292         static const char *profile_name[] = {
1293                                         "BOOTUP_DEFAULT",
1294                                         "3D_FULL_SCREEN",
1295                                         "POWER_SAVING",
1296                                         "VIDEO",
1297                                         "VR",
1298                                         "COMPUTE",
1299                                         "CUSTOM"};
1300         static const char *title[] = {
1301                         "PROFILE_INDEX(NAME)",
1302                         "CLOCK_TYPE(NAME)",
1303                         "FPS",
1304                         "MinFreqType",
1305                         "MinActiveFreqType",
1306                         "MinActiveFreq",
1307                         "BoosterFreqType",
1308                         "BoosterFreq",
1309                         "PD_Data_limit_c",
1310                         "PD_Data_error_coeff",
1311                         "PD_Data_error_rate_coeff"};
1312         int result = 0;
1313
1314         if (!buf)
1315                 return -EINVAL;
1316
1317         size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n",
1318                         title[0], title[1], title[2], title[3], title[4], title[5],
1319                         title[6], title[7], title[8], title[9], title[10]);
1320
1321         for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
1322                 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1323                 workload_type = smu_cmn_to_asic_specific_index(smu,
1324                                                                CMN2ASIC_MAPPING_WORKLOAD,
1325                                                                i);
1326                 if (workload_type < 0)
1327                         return -EINVAL;
1328
1329                 result = smu_cmn_update_table(smu,
1330                                           SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
1331                                           (void *)(&activity_monitor_external), false);
1332                 if (result) {
1333                         dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1334                         return result;
1335                 }
1336
1337                 size += sprintf(buf + size, "%2d %14s%s:\n",
1338                         i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
1339
1340                 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1341                         " ",
1342                         0,
1343                         "GFXCLK",
1344                         activity_monitor->Gfx_FPS,
1345                         activity_monitor->Gfx_MinFreqStep,
1346                         activity_monitor->Gfx_MinActiveFreqType,
1347                         activity_monitor->Gfx_MinActiveFreq,
1348                         activity_monitor->Gfx_BoosterFreqType,
1349                         activity_monitor->Gfx_BoosterFreq,
1350                         activity_monitor->Gfx_PD_Data_limit_c,
1351                         activity_monitor->Gfx_PD_Data_error_coeff,
1352                         activity_monitor->Gfx_PD_Data_error_rate_coeff);
1353
1354                 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1355                         " ",
1356                         1,
1357                         "SOCCLK",
1358                         activity_monitor->Fclk_FPS,
1359                         activity_monitor->Fclk_MinFreqStep,
1360                         activity_monitor->Fclk_MinActiveFreqType,
1361                         activity_monitor->Fclk_MinActiveFreq,
1362                         activity_monitor->Fclk_BoosterFreqType,
1363                         activity_monitor->Fclk_BoosterFreq,
1364                         activity_monitor->Fclk_PD_Data_limit_c,
1365                         activity_monitor->Fclk_PD_Data_error_coeff,
1366                         activity_monitor->Fclk_PD_Data_error_rate_coeff);
1367
1368                 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1369                         " ",
1370                         2,
1371                         "MEMLK",
1372                         activity_monitor->Mem_FPS,
1373                         activity_monitor->Mem_MinFreqStep,
1374                         activity_monitor->Mem_MinActiveFreqType,
1375                         activity_monitor->Mem_MinActiveFreq,
1376                         activity_monitor->Mem_BoosterFreqType,
1377                         activity_monitor->Mem_BoosterFreq,
1378                         activity_monitor->Mem_PD_Data_limit_c,
1379                         activity_monitor->Mem_PD_Data_error_coeff,
1380                         activity_monitor->Mem_PD_Data_error_rate_coeff);
1381         }
1382
1383         return size;
1384 }
1385
1386 static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
1387 {
1388
1389         DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
1390         DpmActivityMonitorCoeffInt_t *activity_monitor =
1391                 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
1392         int workload_type, ret = 0;
1393
1394         smu->power_profile_mode = input[size];
1395
1396         if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
1397                 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);
1398                 return -EINVAL;
1399         }
1400
1401         if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
1402
1403                 ret = smu_cmn_update_table(smu,
1404                                        SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
1405                                        (void *)(&activity_monitor_external), false);
1406                 if (ret) {
1407                         dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1408                         return ret;
1409                 }
1410
1411                 switch (input[0]) {
1412                 case 0: /* Gfxclk */
1413                         activity_monitor->Gfx_FPS = input[1];
1414                         activity_monitor->Gfx_MinFreqStep = input[2];
1415                         activity_monitor->Gfx_MinActiveFreqType = input[3];
1416                         activity_monitor->Gfx_MinActiveFreq = input[4];
1417                         activity_monitor->Gfx_BoosterFreqType = input[5];
1418                         activity_monitor->Gfx_BoosterFreq = input[6];
1419                         activity_monitor->Gfx_PD_Data_limit_c = input[7];
1420                         activity_monitor->Gfx_PD_Data_error_coeff = input[8];
1421                         activity_monitor->Gfx_PD_Data_error_rate_coeff = input[9];
1422                         break;
1423                 case 1: /* Socclk */
1424                         activity_monitor->Fclk_FPS = input[1];
1425                         activity_monitor->Fclk_MinFreqStep = input[2];
1426                         activity_monitor->Fclk_MinActiveFreqType = input[3];
1427                         activity_monitor->Fclk_MinActiveFreq = input[4];
1428                         activity_monitor->Fclk_BoosterFreqType = input[5];
1429                         activity_monitor->Fclk_BoosterFreq = input[6];
1430                         activity_monitor->Fclk_PD_Data_limit_c = input[7];
1431                         activity_monitor->Fclk_PD_Data_error_coeff = input[8];
1432                         activity_monitor->Fclk_PD_Data_error_rate_coeff = input[9];
1433                         break;
1434                 case 2: /* Memlk */
1435                         activity_monitor->Mem_FPS = input[1];
1436                         activity_monitor->Mem_MinFreqStep = input[2];
1437                         activity_monitor->Mem_MinActiveFreqType = input[3];
1438                         activity_monitor->Mem_MinActiveFreq = input[4];
1439                         activity_monitor->Mem_BoosterFreqType = input[5];
1440                         activity_monitor->Mem_BoosterFreq = input[6];
1441                         activity_monitor->Mem_PD_Data_limit_c = input[7];
1442                         activity_monitor->Mem_PD_Data_error_coeff = input[8];
1443                         activity_monitor->Mem_PD_Data_error_rate_coeff = input[9];
1444                         break;
1445                 }
1446
1447                 ret = smu_cmn_update_table(smu,
1448                                        SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
1449                                        (void *)(&activity_monitor_external), true);
1450                 if (ret) {
1451                         dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
1452                         return ret;
1453                 }
1454         }
1455
1456         /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1457         workload_type = smu_cmn_to_asic_specific_index(smu,
1458                                                        CMN2ASIC_MAPPING_WORKLOAD,
1459                                                        smu->power_profile_mode);
1460         if (workload_type < 0)
1461                 return -EINVAL;
1462         smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1463                                     1 << workload_type, NULL);
1464
1465         return ret;
1466 }
1467
1468 static int sienna_cichlid_notify_smc_display_config(struct smu_context *smu)
1469 {
1470         struct smu_clocks min_clocks = {0};
1471         struct pp_display_clock_request clock_req;
1472         int ret = 0;
1473
1474         min_clocks.dcef_clock = smu->display_config->min_dcef_set_clk;
1475         min_clocks.dcef_clock_in_sr = smu->display_config->min_dcef_deep_sleep_set_clk;
1476         min_clocks.memory_clock = smu->display_config->min_mem_set_clock;
1477
1478         if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
1479                 clock_req.clock_type = amd_pp_dcef_clock;
1480                 clock_req.clock_freq_in_khz = min_clocks.dcef_clock * 10;
1481
1482                 ret = smu_v11_0_display_clock_voltage_request(smu, &clock_req);
1483                 if (!ret) {
1484                         if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_DCEFCLK_BIT)) {
1485                                 ret = smu_cmn_send_smc_msg_with_param(smu,
1486                                                                   SMU_MSG_SetMinDeepSleepDcefclk,
1487                                                                   min_clocks.dcef_clock_in_sr/100,
1488                                                                   NULL);
1489                                 if (ret) {
1490                                         dev_err(smu->adev->dev, "Attempt to set divider for DCEFCLK Failed!");
1491                                         return ret;
1492                                 }
1493                         }
1494                 } else {
1495                         dev_info(smu->adev->dev, "Attempt to set Hard Min for DCEFCLK Failed!");
1496                 }
1497         }
1498
1499         if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
1500                 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_clocks.memory_clock/100, 0);
1501                 if (ret) {
1502                         dev_err(smu->adev->dev, "[%s] Set hard min uclk failed!", __func__);
1503                         return ret;
1504                 }
1505         }
1506
1507         return 0;
1508 }
1509
1510 static int sienna_cichlid_set_watermarks_table(struct smu_context *smu,
1511                                                struct pp_smu_wm_range_sets *clock_ranges)
1512 {
1513         Watermarks_t *table = smu->smu_table.watermarks_table;
1514         int ret = 0;
1515         int i;
1516
1517         if (clock_ranges) {
1518                 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES ||
1519                     clock_ranges->num_writer_wm_sets > NUM_WM_RANGES)
1520                         return -EINVAL;
1521
1522                 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
1523                         table->WatermarkRow[WM_DCEFCLK][i].MinClock =
1524                                 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
1525                         table->WatermarkRow[WM_DCEFCLK][i].MaxClock =
1526                                 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
1527                         table->WatermarkRow[WM_DCEFCLK][i].MinUclk =
1528                                 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
1529                         table->WatermarkRow[WM_DCEFCLK][i].MaxUclk =
1530                                 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
1531
1532                         table->WatermarkRow[WM_DCEFCLK][i].WmSetting =
1533                                 clock_ranges->reader_wm_sets[i].wm_inst;
1534                 }
1535
1536                 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
1537                         table->WatermarkRow[WM_SOCCLK][i].MinClock =
1538                                 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
1539                         table->WatermarkRow[WM_SOCCLK][i].MaxClock =
1540                                 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
1541                         table->WatermarkRow[WM_SOCCLK][i].MinUclk =
1542                                 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
1543                         table->WatermarkRow[WM_SOCCLK][i].MaxUclk =
1544                                 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
1545
1546                         table->WatermarkRow[WM_SOCCLK][i].WmSetting =
1547                                 clock_ranges->writer_wm_sets[i].wm_inst;
1548                 }
1549
1550                 smu->watermarks_bitmap |= WATERMARKS_EXIST;
1551         }
1552
1553         if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
1554              !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
1555                 ret = smu_cmn_write_watermarks_table(smu);
1556                 if (ret) {
1557                         dev_err(smu->adev->dev, "Failed to update WMTABLE!");
1558                         return ret;
1559                 }
1560                 smu->watermarks_bitmap |= WATERMARKS_LOADED;
1561         }
1562
1563         return 0;
1564 }
1565
1566 static int sienna_cichlid_read_sensor(struct smu_context *smu,
1567                                  enum amd_pp_sensors sensor,
1568                                  void *data, uint32_t *size)
1569 {
1570         int ret = 0;
1571         struct smu_table_context *table_context = &smu->smu_table;
1572         PPTable_t *pptable = table_context->driver_pptable;
1573
1574         if(!data || !size)
1575                 return -EINVAL;
1576
1577         mutex_lock(&smu->sensor_lock);
1578         switch (sensor) {
1579         case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
1580                 *(uint32_t *)data = pptable->FanMaximumRpm;
1581                 *size = 4;
1582                 break;
1583         case AMDGPU_PP_SENSOR_MEM_LOAD:
1584                 ret = sienna_cichlid_get_smu_metrics_data(smu,
1585                                                           METRICS_AVERAGE_MEMACTIVITY,
1586                                                           (uint32_t *)data);
1587                 *size = 4;
1588                 break;
1589         case AMDGPU_PP_SENSOR_GPU_LOAD:
1590                 ret = sienna_cichlid_get_smu_metrics_data(smu,
1591                                                           METRICS_AVERAGE_GFXACTIVITY,
1592                                                           (uint32_t *)data);
1593                 *size = 4;
1594                 break;
1595         case AMDGPU_PP_SENSOR_GPU_POWER:
1596                 ret = sienna_cichlid_get_smu_metrics_data(smu,
1597                                                           METRICS_AVERAGE_SOCKETPOWER,
1598                                                           (uint32_t *)data);
1599                 *size = 4;
1600                 break;
1601         case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1602                 ret = sienna_cichlid_get_smu_metrics_data(smu,
1603                                                           METRICS_TEMPERATURE_HOTSPOT,
1604                                                           (uint32_t *)data);
1605                 *size = 4;
1606                 break;
1607         case AMDGPU_PP_SENSOR_EDGE_TEMP:
1608                 ret = sienna_cichlid_get_smu_metrics_data(smu,
1609                                                           METRICS_TEMPERATURE_EDGE,
1610                                                           (uint32_t *)data);
1611                 *size = 4;
1612                 break;
1613         case AMDGPU_PP_SENSOR_MEM_TEMP:
1614                 ret = sienna_cichlid_get_smu_metrics_data(smu,
1615                                                           METRICS_TEMPERATURE_MEM,
1616                                                           (uint32_t *)data);
1617                 *size = 4;
1618                 break;
1619         case AMDGPU_PP_SENSOR_GFX_MCLK:
1620                 ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data);
1621                 *(uint32_t *)data *= 100;
1622                 *size = 4;
1623                 break;
1624         case AMDGPU_PP_SENSOR_GFX_SCLK:
1625                 ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data);
1626                 *(uint32_t *)data *= 100;
1627                 *size = 4;
1628                 break;
1629         case AMDGPU_PP_SENSOR_VDDGFX:
1630                 ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data);
1631                 *size = 4;
1632                 break;
1633         default:
1634                 ret = -EOPNOTSUPP;
1635                 break;
1636         }
1637         mutex_unlock(&smu->sensor_lock);
1638
1639         return ret;
1640 }
1641
1642 static int sienna_cichlid_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states)
1643 {
1644         uint32_t num_discrete_levels = 0;
1645         uint16_t *dpm_levels = NULL;
1646         uint16_t i = 0;
1647         struct smu_table_context *table_context = &smu->smu_table;
1648         PPTable_t *driver_ppt = NULL;
1649
1650         if (!clocks_in_khz || !num_states || !table_context->driver_pptable)
1651                 return -EINVAL;
1652
1653         driver_ppt = table_context->driver_pptable;
1654         num_discrete_levels = driver_ppt->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels;
1655         dpm_levels = driver_ppt->FreqTableUclk;
1656
1657         if (num_discrete_levels == 0 || dpm_levels == NULL)
1658                 return -EINVAL;
1659
1660         *num_states = num_discrete_levels;
1661         for (i = 0; i < num_discrete_levels; i++) {
1662                 /* convert to khz */
1663                 *clocks_in_khz = (*dpm_levels) * 1000;
1664                 clocks_in_khz++;
1665                 dpm_levels++;
1666         }
1667
1668         return 0;
1669 }
1670
1671 static int sienna_cichlid_get_thermal_temperature_range(struct smu_context *smu,
1672                                                 struct smu_temperature_range *range)
1673 {
1674         struct smu_table_context *table_context = &smu->smu_table;
1675         struct smu_11_0_7_powerplay_table *powerplay_table =
1676                                 table_context->power_play_table;
1677         PPTable_t *pptable = smu->smu_table.driver_pptable;
1678
1679         if (!range)
1680                 return -EINVAL;
1681
1682         memcpy(range, &smu11_thermal_policy[0], sizeof(struct smu_temperature_range));
1683
1684         range->max = pptable->TemperatureLimit[TEMP_EDGE] *
1685                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1686         range->edge_emergency_max = (pptable->TemperatureLimit[TEMP_EDGE] + CTF_OFFSET_EDGE) *
1687                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1688         range->hotspot_crit_max = pptable->TemperatureLimit[TEMP_HOTSPOT] *
1689                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1690         range->hotspot_emergency_max = (pptable->TemperatureLimit[TEMP_HOTSPOT] + CTF_OFFSET_HOTSPOT) *
1691                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1692         range->mem_crit_max = pptable->TemperatureLimit[TEMP_MEM] *
1693                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1694         range->mem_emergency_max = (pptable->TemperatureLimit[TEMP_MEM] + CTF_OFFSET_MEM)*
1695                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1696         range->software_shutdown_temp = powerplay_table->software_shutdown_temp;
1697
1698         return 0;
1699 }
1700
1701 static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context *smu,
1702                                                 bool disable_memory_clock_switch)
1703 {
1704         int ret = 0;
1705         struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks =
1706                 (struct smu_11_0_max_sustainable_clocks *)
1707                         smu->smu_table.max_sustainable_clocks;
1708         uint32_t min_memory_clock = smu->hard_min_uclk_req_from_dal;
1709         uint32_t max_memory_clock = max_sustainable_clocks->uclock;
1710
1711         if(smu->disable_uclk_switch == disable_memory_clock_switch)
1712                 return 0;
1713
1714         if(disable_memory_clock_switch)
1715                 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, max_memory_clock, 0);
1716         else
1717                 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_memory_clock, 0);
1718
1719         if(!ret)
1720                 smu->disable_uclk_switch = disable_memory_clock_switch;
1721
1722         return ret;
1723 }
1724
1725 static int sienna_cichlid_get_power_limit(struct smu_context *smu)
1726 {
1727         struct smu_11_0_7_powerplay_table *powerplay_table =
1728                 (struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table;
1729         PPTable_t *pptable = smu->smu_table.driver_pptable;
1730         uint32_t power_limit, od_percent;
1731
1732         if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
1733                 /* the last hope to figure out the ppt limit */
1734                 if (!pptable) {
1735                         dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!");
1736                         return -EINVAL;
1737                 }
1738                 power_limit =
1739                         pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
1740         }
1741         smu->current_power_limit = smu->default_power_limit = power_limit;
1742
1743         if (smu->od_enabled) {
1744                 od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
1745
1746                 dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
1747
1748                 power_limit *= (100 + od_percent);
1749                 power_limit /= 100;
1750         }
1751         smu->max_power_limit = power_limit;
1752
1753         return 0;
1754 }
1755
1756 static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
1757                                          uint32_t pcie_gen_cap,
1758                                          uint32_t pcie_width_cap)
1759 {
1760         struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
1761         PPTable_t *pptable = smu->smu_table.driver_pptable;
1762         uint32_t smu_pcie_arg;
1763         int ret, i;
1764
1765         /* lclk dpm table setup */
1766         for (i = 0; i < MAX_PCIE_CONF; i++) {
1767                 dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pptable->PcieGenSpeed[i];
1768                 dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pptable->PcieLaneCount[i];
1769         }
1770
1771         for (i = 0; i < NUM_LINK_LEVELS; i++) {
1772                 smu_pcie_arg = (i << 16) |
1773                         ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ?
1774                                         (pptable->PcieGenSpeed[i] << 8) :
1775                                         (pcie_gen_cap << 8)) |
1776                         ((pptable->PcieLaneCount[i] <= pcie_width_cap) ?
1777                                         pptable->PcieLaneCount[i] :
1778                                         pcie_width_cap);
1779
1780                 ret = smu_cmn_send_smc_msg_with_param(smu,
1781                                           SMU_MSG_OverridePcieParameters,
1782                                           smu_pcie_arg,
1783                                           NULL);
1784
1785                 if (ret)
1786                         return ret;
1787
1788                 if (pptable->PcieGenSpeed[i] > pcie_gen_cap)
1789                         dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pcie_gen_cap;
1790                 if (pptable->PcieLaneCount[i] > pcie_width_cap)
1791                         dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pcie_width_cap;
1792         }
1793
1794         return 0;
1795 }
1796
1797 static int sienna_cichlid_get_dpm_ultimate_freq(struct smu_context *smu,
1798                                 enum smu_clk_type clk_type,
1799                                 uint32_t *min, uint32_t *max)
1800 {
1801         struct amdgpu_device *adev = smu->adev;
1802         int ret;
1803
1804         if (clk_type == SMU_GFXCLK)
1805                 amdgpu_gfx_off_ctrl(adev, false);
1806         ret = smu_v11_0_get_dpm_ultimate_freq(smu, clk_type, min, max);
1807         if (clk_type == SMU_GFXCLK)
1808                 amdgpu_gfx_off_ctrl(adev, true);
1809
1810         return ret;
1811 }
1812
1813 static void sienna_cichlid_dump_od_table(struct smu_context *smu,
1814                                          OverDriveTable_t *od_table)
1815 {
1816         struct amdgpu_device *adev = smu->adev;
1817         uint32_t smu_version;
1818
1819         dev_dbg(smu->adev->dev, "OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin,
1820                                                           od_table->GfxclkFmax);
1821         dev_dbg(smu->adev->dev, "OD: Uclk: (%d, %d)\n", od_table->UclkFmin,
1822                                                         od_table->UclkFmax);
1823
1824         smu_cmn_get_smc_version(smu, NULL, &smu_version);
1825         if (!((adev->asic_type == CHIP_SIENNA_CICHLID) &&
1826                (smu_version < 0x003a2900)))
1827                 dev_dbg(smu->adev->dev, "OD: VddGfxOffset: %d\n", od_table->VddGfxOffset);
1828 }
1829
1830 static int sienna_cichlid_set_default_od_settings(struct smu_context *smu)
1831 {
1832         OverDriveTable_t *od_table =
1833                 (OverDriveTable_t *)smu->smu_table.overdrive_table;
1834         OverDriveTable_t *boot_od_table =
1835                 (OverDriveTable_t *)smu->smu_table.boot_overdrive_table;
1836         int ret = 0;
1837
1838         ret = smu_cmn_update_table(smu, SMU_TABLE_OVERDRIVE,
1839                                    0, (void *)od_table, false);
1840         if (ret) {
1841                 dev_err(smu->adev->dev, "Failed to get overdrive table!\n");
1842                 return ret;
1843         }
1844
1845         memcpy(boot_od_table, od_table, sizeof(OverDriveTable_t));
1846
1847         sienna_cichlid_dump_od_table(smu, od_table);
1848
1849         return 0;
1850 }
1851
1852 static int sienna_cichlid_od_setting_check_range(struct smu_context *smu,
1853                                                  struct smu_11_0_7_overdrive_table *od_table,
1854                                                  enum SMU_11_0_7_ODSETTING_ID setting,
1855                                                  uint32_t value)
1856 {
1857         if (value < od_table->min[setting]) {
1858                 dev_warn(smu->adev->dev, "OD setting (%d, %d) is less than the minimum allowed (%d)\n",
1859                                           setting, value, od_table->min[setting]);
1860                 return -EINVAL;
1861         }
1862         if (value > od_table->max[setting]) {
1863                 dev_warn(smu->adev->dev, "OD setting (%d, %d) is greater than the maximum allowed (%d)\n",
1864                                           setting, value, od_table->max[setting]);
1865                 return -EINVAL;
1866         }
1867
1868         return 0;
1869 }
1870
1871 static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu,
1872                                             enum PP_OD_DPM_TABLE_COMMAND type,
1873                                             long input[], uint32_t size)
1874 {
1875         struct smu_table_context *table_context = &smu->smu_table;
1876         OverDriveTable_t *od_table =
1877                 (OverDriveTable_t *)table_context->overdrive_table;
1878         struct smu_11_0_7_overdrive_table *od_settings =
1879                 (struct smu_11_0_7_overdrive_table *)smu->od_settings;
1880         struct amdgpu_device *adev = smu->adev;
1881         enum SMU_11_0_7_ODSETTING_ID freq_setting;
1882         uint16_t *freq_ptr;
1883         int i, ret = 0;
1884         uint32_t smu_version;
1885
1886         if (!smu->od_enabled) {
1887                 dev_warn(smu->adev->dev, "OverDrive is not enabled!\n");
1888                 return -EINVAL;
1889         }
1890
1891         if (!smu->od_settings) {
1892                 dev_err(smu->adev->dev, "OD board limits are not set!\n");
1893                 return -ENOENT;
1894         }
1895
1896         if (!(table_context->overdrive_table && table_context->boot_overdrive_table)) {
1897                 dev_err(smu->adev->dev, "Overdrive table was not initialized!\n");
1898                 return -EINVAL;
1899         }
1900
1901         switch (type) {
1902         case PP_OD_EDIT_SCLK_VDDC_TABLE:
1903                 if (!sienna_cichlid_is_od_feature_supported(od_settings,
1904                                                             SMU_11_0_7_ODCAP_GFXCLK_LIMITS)) {
1905                         dev_warn(smu->adev->dev, "GFXCLK_LIMITS not supported!\n");
1906                         return -ENOTSUPP;
1907                 }
1908
1909                 for (i = 0; i < size; i += 2) {
1910                         if (i + 2 > size) {
1911                                 dev_info(smu->adev->dev, "invalid number of input parameters %d\n", size);
1912                                 return -EINVAL;
1913                         }
1914
1915                         switch (input[i]) {
1916                         case 0:
1917                                 if (input[i + 1] > od_table->GfxclkFmax) {
1918                                         dev_info(smu->adev->dev, "GfxclkFmin (%ld) must be <= GfxclkFmax (%u)!\n",
1919                                                 input[i + 1], od_table->GfxclkFmax);
1920                                         return -EINVAL;
1921                                 }
1922
1923                                 freq_setting = SMU_11_0_7_ODSETTING_GFXCLKFMIN;
1924                                 freq_ptr = &od_table->GfxclkFmin;
1925                                 break;
1926
1927                         case 1:
1928                                 if (input[i + 1] < od_table->GfxclkFmin) {
1929                                         dev_info(smu->adev->dev, "GfxclkFmax (%ld) must be >= GfxclkFmin (%u)!\n",
1930                                                 input[i + 1], od_table->GfxclkFmin);
1931                                         return -EINVAL;
1932                                 }
1933
1934                                 freq_setting = SMU_11_0_7_ODSETTING_GFXCLKFMAX;
1935                                 freq_ptr = &od_table->GfxclkFmax;
1936                                 break;
1937
1938                         default:
1939                                 dev_info(smu->adev->dev, "Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
1940                                 dev_info(smu->adev->dev, "Supported indices: [0:min,1:max]\n");
1941                                 return -EINVAL;
1942                         }
1943
1944                         ret = sienna_cichlid_od_setting_check_range(smu, od_settings,
1945                                                                     freq_setting, input[i + 1]);
1946                         if (ret)
1947                                 return ret;
1948
1949                         *freq_ptr = (uint16_t)input[i + 1];
1950                 }
1951                 break;
1952
1953         case PP_OD_EDIT_MCLK_VDDC_TABLE:
1954                 if (!sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_UCLK_LIMITS)) {
1955                         dev_warn(smu->adev->dev, "UCLK_LIMITS not supported!\n");
1956                         return -ENOTSUPP;
1957                 }
1958
1959                 for (i = 0; i < size; i += 2) {
1960                         if (i + 2 > size) {
1961                                 dev_info(smu->adev->dev, "invalid number of input parameters %d\n", size);
1962                                 return -EINVAL;
1963                         }
1964
1965                         switch (input[i]) {
1966                         case 0:
1967                                 if (input[i + 1] > od_table->UclkFmax) {
1968                                         dev_info(smu->adev->dev, "UclkFmin (%ld) must be <= UclkFmax (%u)!\n",
1969                                                 input[i + 1], od_table->UclkFmax);
1970                                         return -EINVAL;
1971                                 }
1972
1973                                 freq_setting = SMU_11_0_7_ODSETTING_UCLKFMIN;
1974                                 freq_ptr = &od_table->UclkFmin;
1975                                 break;
1976
1977                         case 1:
1978                                 if (input[i + 1] < od_table->UclkFmin) {
1979                                         dev_info(smu->adev->dev, "UclkFmax (%ld) must be >= UclkFmin (%u)!\n",
1980                                                 input[i + 1], od_table->UclkFmin);
1981                                         return -EINVAL;
1982                                 }
1983
1984                                 freq_setting = SMU_11_0_7_ODSETTING_UCLKFMAX;
1985                                 freq_ptr = &od_table->UclkFmax;
1986                                 break;
1987
1988                         default:
1989                                 dev_info(smu->adev->dev, "Invalid MCLK_VDDC_TABLE index: %ld\n", input[i]);
1990                                 dev_info(smu->adev->dev, "Supported indices: [0:min,1:max]\n");
1991                                 return -EINVAL;
1992                         }
1993
1994                         ret = sienna_cichlid_od_setting_check_range(smu, od_settings,
1995                                                                     freq_setting, input[i + 1]);
1996                         if (ret)
1997                                 return ret;
1998
1999                         *freq_ptr = (uint16_t)input[i + 1];
2000                 }
2001                 break;
2002
2003         case PP_OD_RESTORE_DEFAULT_TABLE:
2004                 memcpy(table_context->overdrive_table,
2005                                 table_context->boot_overdrive_table,
2006                                 sizeof(OverDriveTable_t));
2007                 fallthrough;
2008
2009         case PP_OD_COMMIT_DPM_TABLE:
2010                 sienna_cichlid_dump_od_table(smu, od_table);
2011
2012                 ret = smu_cmn_update_table(smu, SMU_TABLE_OVERDRIVE,
2013                                            0, (void *)od_table, true);
2014                 if (ret) {
2015                         dev_err(smu->adev->dev, "Failed to import overdrive table!\n");
2016                         return ret;
2017                 }
2018                 break;
2019
2020         case PP_OD_EDIT_VDDGFX_OFFSET:
2021                 if (size != 1) {
2022                         dev_info(smu->adev->dev, "invalid number of parameters: %d\n", size);
2023                         return -EINVAL;
2024                 }
2025
2026                 /*
2027                  * OD GFX Voltage Offset functionality is supported only by 58.41.0
2028                  * and onwards SMU firmwares.
2029                  */
2030                 smu_cmn_get_smc_version(smu, NULL, &smu_version);
2031                 if ((adev->asic_type == CHIP_SIENNA_CICHLID) &&
2032                      (smu_version < 0x003a2900)) {
2033                         dev_err(smu->adev->dev, "OD GFX Voltage offset functionality is supported "
2034                                                 "only by 58.41.0 and onwards SMU firmwares!\n");
2035                         return -EOPNOTSUPP;
2036                 }
2037
2038                 od_table->VddGfxOffset = (int16_t)input[0];
2039
2040                 sienna_cichlid_dump_od_table(smu, od_table);
2041                 break;
2042
2043         default:
2044                 return -ENOSYS;
2045         }
2046
2047         return ret;
2048 }
2049
2050 static int sienna_cichlid_run_btc(struct smu_context *smu)
2051 {
2052         return smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
2053 }
2054
2055 static bool sienna_cichlid_is_baco_supported(struct smu_context *smu)
2056 {
2057         struct amdgpu_device *adev = smu->adev;
2058         uint32_t val;
2059
2060         if (amdgpu_sriov_vf(adev) || (!smu_v11_0_baco_is_support(smu)))
2061                 return false;
2062
2063         val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
2064         return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false;
2065 }
2066
2067 static bool sienna_cichlid_is_mode1_reset_supported(struct smu_context *smu)
2068 {
2069         struct amdgpu_device *adev = smu->adev;
2070         uint32_t val;
2071         u32 smu_version;
2072
2073         /**
2074          * SRIOV env will not support SMU mode1 reset
2075          * PM FW support mode1 reset from 58.26
2076          */
2077         smu_cmn_get_smc_version(smu, NULL, &smu_version);
2078         if (amdgpu_sriov_vf(adev) || (smu_version < 0x003a1a00))
2079                 return false;
2080
2081         /**
2082          * mode1 reset relies on PSP, so we should check if
2083          * PSP is alive.
2084          */
2085         val = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
2086         return val != 0x0;
2087 }
2088
2089 static void sienna_cichlid_dump_pptable(struct smu_context *smu)
2090 {
2091         struct smu_table_context *table_context = &smu->smu_table;
2092         PPTable_t *pptable = table_context->driver_pptable;
2093         int i;
2094
2095         dev_info(smu->adev->dev, "Dumped PPTable:\n");
2096
2097         dev_info(smu->adev->dev, "Version = 0x%08x\n", pptable->Version);
2098         dev_info(smu->adev->dev, "FeaturesToRun[0] = 0x%08x\n", pptable->FeaturesToRun[0]);
2099         dev_info(smu->adev->dev, "FeaturesToRun[1] = 0x%08x\n", pptable->FeaturesToRun[1]);
2100
2101         for (i = 0; i < PPT_THROTTLER_COUNT; i++) {
2102                 dev_info(smu->adev->dev, "SocketPowerLimitAc[%d] = 0x%x\n", i, pptable->SocketPowerLimitAc[i]);
2103                 dev_info(smu->adev->dev, "SocketPowerLimitAcTau[%d] = 0x%x\n", i, pptable->SocketPowerLimitAcTau[i]);
2104                 dev_info(smu->adev->dev, "SocketPowerLimitDc[%d] = 0x%x\n", i, pptable->SocketPowerLimitDc[i]);
2105                 dev_info(smu->adev->dev, "SocketPowerLimitDcTau[%d] = 0x%x\n", i, pptable->SocketPowerLimitDcTau[i]);
2106         }
2107
2108         for (i = 0; i < TDC_THROTTLER_COUNT; i++) {
2109                 dev_info(smu->adev->dev, "TdcLimit[%d] = 0x%x\n", i, pptable->TdcLimit[i]);
2110                 dev_info(smu->adev->dev, "TdcLimitTau[%d] = 0x%x\n", i, pptable->TdcLimitTau[i]);
2111         }
2112
2113         for (i = 0; i < TEMP_COUNT; i++) {
2114                 dev_info(smu->adev->dev, "TemperatureLimit[%d] = 0x%x\n", i, pptable->TemperatureLimit[i]);
2115         }
2116
2117         dev_info(smu->adev->dev, "FitLimit = 0x%x\n", pptable->FitLimit);
2118         dev_info(smu->adev->dev, "TotalPowerConfig = 0x%x\n", pptable->TotalPowerConfig);
2119         dev_info(smu->adev->dev, "TotalPowerPadding[0] = 0x%x\n", pptable->TotalPowerPadding[0]);
2120         dev_info(smu->adev->dev, "TotalPowerPadding[1] = 0x%x\n", pptable->TotalPowerPadding[1]);
2121         dev_info(smu->adev->dev, "TotalPowerPadding[2] = 0x%x\n", pptable->TotalPowerPadding[2]);
2122
2123         dev_info(smu->adev->dev, "ApccPlusResidencyLimit = 0x%x\n", pptable->ApccPlusResidencyLimit);
2124         for (i = 0; i < NUM_SMNCLK_DPM_LEVELS; i++) {
2125                 dev_info(smu->adev->dev, "SmnclkDpmFreq[%d] = 0x%x\n", i, pptable->SmnclkDpmFreq[i]);
2126                 dev_info(smu->adev->dev, "SmnclkDpmVoltage[%d] = 0x%x\n", i, pptable->SmnclkDpmVoltage[i]);
2127         }
2128         dev_info(smu->adev->dev, "ThrottlerControlMask = 0x%x\n", pptable->ThrottlerControlMask);
2129
2130         dev_info(smu->adev->dev, "FwDStateMask = 0x%x\n", pptable->FwDStateMask);
2131
2132         dev_info(smu->adev->dev, "UlvVoltageOffsetSoc = 0x%x\n", pptable->UlvVoltageOffsetSoc);
2133         dev_info(smu->adev->dev, "UlvVoltageOffsetGfx = 0x%x\n", pptable->UlvVoltageOffsetGfx);
2134         dev_info(smu->adev->dev, "MinVoltageUlvGfx = 0x%x\n", pptable->MinVoltageUlvGfx);
2135         dev_info(smu->adev->dev, "MinVoltageUlvSoc = 0x%x\n", pptable->MinVoltageUlvSoc);
2136
2137         dev_info(smu->adev->dev, "SocLIVmin = 0x%x\n", pptable->SocLIVmin);
2138         dev_info(smu->adev->dev, "PaddingLIVmin = 0x%x\n", pptable->PaddingLIVmin);
2139
2140         dev_info(smu->adev->dev, "GceaLinkMgrIdleThreshold = 0x%x\n", pptable->GceaLinkMgrIdleThreshold);
2141         dev_info(smu->adev->dev, "paddingRlcUlvParams[0] = 0x%x\n", pptable->paddingRlcUlvParams[0]);
2142         dev_info(smu->adev->dev, "paddingRlcUlvParams[1] = 0x%x\n", pptable->paddingRlcUlvParams[1]);
2143         dev_info(smu->adev->dev, "paddingRlcUlvParams[2] = 0x%x\n", pptable->paddingRlcUlvParams[2]);
2144
2145         dev_info(smu->adev->dev, "MinVoltageGfx = 0x%x\n", pptable->MinVoltageGfx);
2146         dev_info(smu->adev->dev, "MinVoltageSoc = 0x%x\n", pptable->MinVoltageSoc);
2147         dev_info(smu->adev->dev, "MaxVoltageGfx = 0x%x\n", pptable->MaxVoltageGfx);
2148         dev_info(smu->adev->dev, "MaxVoltageSoc = 0x%x\n", pptable->MaxVoltageSoc);
2149
2150         dev_info(smu->adev->dev, "LoadLineResistanceGfx = 0x%x\n", pptable->LoadLineResistanceGfx);
2151         dev_info(smu->adev->dev, "LoadLineResistanceSoc = 0x%x\n", pptable->LoadLineResistanceSoc);
2152
2153         dev_info(smu->adev->dev, "VDDGFX_TVmin = 0x%x\n", pptable->VDDGFX_TVmin);
2154         dev_info(smu->adev->dev, "VDDSOC_TVmin = 0x%x\n", pptable->VDDSOC_TVmin);
2155         dev_info(smu->adev->dev, "VDDGFX_Vmin_HiTemp = 0x%x\n", pptable->VDDGFX_Vmin_HiTemp);
2156         dev_info(smu->adev->dev, "VDDGFX_Vmin_LoTemp = 0x%x\n", pptable->VDDGFX_Vmin_LoTemp);
2157         dev_info(smu->adev->dev, "VDDSOC_Vmin_HiTemp = 0x%x\n", pptable->VDDSOC_Vmin_HiTemp);
2158         dev_info(smu->adev->dev, "VDDSOC_Vmin_LoTemp = 0x%x\n", pptable->VDDSOC_Vmin_LoTemp);
2159         dev_info(smu->adev->dev, "VDDGFX_TVminHystersis = 0x%x\n", pptable->VDDGFX_TVminHystersis);
2160         dev_info(smu->adev->dev, "VDDSOC_TVminHystersis = 0x%x\n", pptable->VDDSOC_TVminHystersis);
2161
2162         dev_info(smu->adev->dev, "[PPCLK_GFXCLK]\n"
2163                         "  .VoltageMode          = 0x%02x\n"
2164                         "  .SnapToDiscrete       = 0x%02x\n"
2165                         "  .NumDiscreteLevels    = 0x%02x\n"
2166                         "  .padding              = 0x%02x\n"
2167                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2168                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2169                         "  .SsFmin               = 0x%04x\n"
2170                         "  .Padding_16           = 0x%04x\n",
2171                         pptable->DpmDescriptor[PPCLK_GFXCLK].VoltageMode,
2172                         pptable->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete,
2173                         pptable->DpmDescriptor[PPCLK_GFXCLK].NumDiscreteLevels,
2174                         pptable->DpmDescriptor[PPCLK_GFXCLK].Padding,
2175                         pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.m,
2176                         pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.b,
2177                         pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.a,
2178                         pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.b,
2179                         pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.c,
2180                         pptable->DpmDescriptor[PPCLK_GFXCLK].SsFmin,
2181                         pptable->DpmDescriptor[PPCLK_GFXCLK].Padding16);
2182
2183         dev_info(smu->adev->dev, "[PPCLK_SOCCLK]\n"
2184                         "  .VoltageMode          = 0x%02x\n"
2185                         "  .SnapToDiscrete       = 0x%02x\n"
2186                         "  .NumDiscreteLevels    = 0x%02x\n"
2187                         "  .padding              = 0x%02x\n"
2188                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2189                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2190                         "  .SsFmin               = 0x%04x\n"
2191                         "  .Padding_16           = 0x%04x\n",
2192                         pptable->DpmDescriptor[PPCLK_SOCCLK].VoltageMode,
2193                         pptable->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete,
2194                         pptable->DpmDescriptor[PPCLK_SOCCLK].NumDiscreteLevels,
2195                         pptable->DpmDescriptor[PPCLK_SOCCLK].Padding,
2196                         pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.m,
2197                         pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.b,
2198                         pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.a,
2199                         pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.b,
2200                         pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.c,
2201                         pptable->DpmDescriptor[PPCLK_SOCCLK].SsFmin,
2202                         pptable->DpmDescriptor[PPCLK_SOCCLK].Padding16);
2203
2204         dev_info(smu->adev->dev, "[PPCLK_UCLK]\n"
2205                         "  .VoltageMode          = 0x%02x\n"
2206                         "  .SnapToDiscrete       = 0x%02x\n"
2207                         "  .NumDiscreteLevels    = 0x%02x\n"
2208                         "  .padding              = 0x%02x\n"
2209                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2210                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2211                         "  .SsFmin               = 0x%04x\n"
2212                         "  .Padding_16           = 0x%04x\n",
2213                         pptable->DpmDescriptor[PPCLK_UCLK].VoltageMode,
2214                         pptable->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete,
2215                         pptable->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels,
2216                         pptable->DpmDescriptor[PPCLK_UCLK].Padding,
2217                         pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.m,
2218                         pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.b,
2219                         pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.a,
2220                         pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.b,
2221                         pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.c,
2222                         pptable->DpmDescriptor[PPCLK_UCLK].SsFmin,
2223                         pptable->DpmDescriptor[PPCLK_UCLK].Padding16);
2224
2225         dev_info(smu->adev->dev, "[PPCLK_FCLK]\n"
2226                         "  .VoltageMode          = 0x%02x\n"
2227                         "  .SnapToDiscrete       = 0x%02x\n"
2228                         "  .NumDiscreteLevels    = 0x%02x\n"
2229                         "  .padding              = 0x%02x\n"
2230                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2231                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2232                         "  .SsFmin               = 0x%04x\n"
2233                         "  .Padding_16           = 0x%04x\n",
2234                         pptable->DpmDescriptor[PPCLK_FCLK].VoltageMode,
2235                         pptable->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete,
2236                         pptable->DpmDescriptor[PPCLK_FCLK].NumDiscreteLevels,
2237                         pptable->DpmDescriptor[PPCLK_FCLK].Padding,
2238                         pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.m,
2239                         pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.b,
2240                         pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.a,
2241                         pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.b,
2242                         pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.c,
2243                         pptable->DpmDescriptor[PPCLK_FCLK].SsFmin,
2244                         pptable->DpmDescriptor[PPCLK_FCLK].Padding16);
2245
2246         dev_info(smu->adev->dev, "[PPCLK_DCLK_0]\n"
2247                         "  .VoltageMode          = 0x%02x\n"
2248                         "  .SnapToDiscrete       = 0x%02x\n"
2249                         "  .NumDiscreteLevels    = 0x%02x\n"
2250                         "  .padding              = 0x%02x\n"
2251                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2252                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2253                         "  .SsFmin               = 0x%04x\n"
2254                         "  .Padding_16           = 0x%04x\n",
2255                         pptable->DpmDescriptor[PPCLK_DCLK_0].VoltageMode,
2256                         pptable->DpmDescriptor[PPCLK_DCLK_0].SnapToDiscrete,
2257                         pptable->DpmDescriptor[PPCLK_DCLK_0].NumDiscreteLevels,
2258                         pptable->DpmDescriptor[PPCLK_DCLK_0].Padding,
2259                         pptable->DpmDescriptor[PPCLK_DCLK_0].ConversionToAvfsClk.m,
2260                         pptable->DpmDescriptor[PPCLK_DCLK_0].ConversionToAvfsClk.b,
2261                         pptable->DpmDescriptor[PPCLK_DCLK_0].SsCurve.a,
2262                         pptable->DpmDescriptor[PPCLK_DCLK_0].SsCurve.b,
2263                         pptable->DpmDescriptor[PPCLK_DCLK_0].SsCurve.c,
2264                         pptable->DpmDescriptor[PPCLK_DCLK_0].SsFmin,
2265                         pptable->DpmDescriptor[PPCLK_DCLK_0].Padding16);
2266
2267         dev_info(smu->adev->dev, "[PPCLK_VCLK_0]\n"
2268                         "  .VoltageMode          = 0x%02x\n"
2269                         "  .SnapToDiscrete       = 0x%02x\n"
2270                         "  .NumDiscreteLevels    = 0x%02x\n"
2271                         "  .padding              = 0x%02x\n"
2272                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2273                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2274                         "  .SsFmin               = 0x%04x\n"
2275                         "  .Padding_16           = 0x%04x\n",
2276                         pptable->DpmDescriptor[PPCLK_VCLK_0].VoltageMode,
2277                         pptable->DpmDescriptor[PPCLK_VCLK_0].SnapToDiscrete,
2278                         pptable->DpmDescriptor[PPCLK_VCLK_0].NumDiscreteLevels,
2279                         pptable->DpmDescriptor[PPCLK_VCLK_0].Padding,
2280                         pptable->DpmDescriptor[PPCLK_VCLK_0].ConversionToAvfsClk.m,
2281                         pptable->DpmDescriptor[PPCLK_VCLK_0].ConversionToAvfsClk.b,
2282                         pptable->DpmDescriptor[PPCLK_VCLK_0].SsCurve.a,
2283                         pptable->DpmDescriptor[PPCLK_VCLK_0].SsCurve.b,
2284                         pptable->DpmDescriptor[PPCLK_VCLK_0].SsCurve.c,
2285                         pptable->DpmDescriptor[PPCLK_VCLK_0].SsFmin,
2286                         pptable->DpmDescriptor[PPCLK_VCLK_0].Padding16);
2287
2288         dev_info(smu->adev->dev, "[PPCLK_DCLK_1]\n"
2289                         "  .VoltageMode          = 0x%02x\n"
2290                         "  .SnapToDiscrete       = 0x%02x\n"
2291                         "  .NumDiscreteLevels    = 0x%02x\n"
2292                         "  .padding              = 0x%02x\n"
2293                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2294                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2295                         "  .SsFmin               = 0x%04x\n"
2296                         "  .Padding_16           = 0x%04x\n",
2297                         pptable->DpmDescriptor[PPCLK_DCLK_1].VoltageMode,
2298                         pptable->DpmDescriptor[PPCLK_DCLK_1].SnapToDiscrete,
2299                         pptable->DpmDescriptor[PPCLK_DCLK_1].NumDiscreteLevels,
2300                         pptable->DpmDescriptor[PPCLK_DCLK_1].Padding,
2301                         pptable->DpmDescriptor[PPCLK_DCLK_1].ConversionToAvfsClk.m,
2302                         pptable->DpmDescriptor[PPCLK_DCLK_1].ConversionToAvfsClk.b,
2303                         pptable->DpmDescriptor[PPCLK_DCLK_1].SsCurve.a,
2304                         pptable->DpmDescriptor[PPCLK_DCLK_1].SsCurve.b,
2305                         pptable->DpmDescriptor[PPCLK_DCLK_1].SsCurve.c,
2306                         pptable->DpmDescriptor[PPCLK_DCLK_1].SsFmin,
2307                         pptable->DpmDescriptor[PPCLK_DCLK_1].Padding16);
2308
2309         dev_info(smu->adev->dev, "[PPCLK_VCLK_1]\n"
2310                         "  .VoltageMode          = 0x%02x\n"
2311                         "  .SnapToDiscrete       = 0x%02x\n"
2312                         "  .NumDiscreteLevels    = 0x%02x\n"
2313                         "  .padding              = 0x%02x\n"
2314                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
2315                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
2316                         "  .SsFmin               = 0x%04x\n"
2317                         "  .Padding_16           = 0x%04x\n",
2318                         pptable->DpmDescriptor[PPCLK_VCLK_1].VoltageMode,
2319                         pptable->DpmDescriptor[PPCLK_VCLK_1].SnapToDiscrete,
2320                         pptable->DpmDescriptor[PPCLK_VCLK_1].NumDiscreteLevels,
2321                         pptable->DpmDescriptor[PPCLK_VCLK_1].Padding,
2322                         pptable->DpmDescriptor[PPCLK_VCLK_1].ConversionToAvfsClk.m,
2323                         pptable->DpmDescriptor[PPCLK_VCLK_1].ConversionToAvfsClk.b,
2324                         pptable->DpmDescriptor[PPCLK_VCLK_1].SsCurve.a,
2325                         pptable->DpmDescriptor[PPCLK_VCLK_1].SsCurve.b,
2326                         pptable->DpmDescriptor[PPCLK_VCLK_1].SsCurve.c,
2327                         pptable->DpmDescriptor[PPCLK_VCLK_1].SsFmin,
2328                         pptable->DpmDescriptor[PPCLK_VCLK_1].Padding16);
2329
2330         dev_info(smu->adev->dev, "FreqTableGfx\n");
2331         for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++)
2332                 dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableGfx[i]);
2333
2334         dev_info(smu->adev->dev, "FreqTableVclk\n");
2335         for (i = 0; i < NUM_VCLK_DPM_LEVELS; i++)
2336                 dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableVclk[i]);
2337
2338         dev_info(smu->adev->dev, "FreqTableDclk\n");
2339         for (i = 0; i < NUM_DCLK_DPM_LEVELS; i++)
2340                 dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableDclk[i]);
2341
2342         dev_info(smu->adev->dev, "FreqTableSocclk\n");
2343         for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++)
2344                 dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableSocclk[i]);
2345
2346         dev_info(smu->adev->dev, "FreqTableUclk\n");
2347         for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2348                 dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableUclk[i]);
2349
2350         dev_info(smu->adev->dev, "FreqTableFclk\n");
2351         for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++)
2352                 dev_info(smu->adev->dev, "  .[%02d] = 0x%x\n", i, pptable->FreqTableFclk[i]);
2353
2354         dev_info(smu->adev->dev, "DcModeMaxFreq\n");
2355         dev_info(smu->adev->dev, "  .PPCLK_GFXCLK = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_GFXCLK]);
2356         dev_info(smu->adev->dev, "  .PPCLK_SOCCLK = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_SOCCLK]);
2357         dev_info(smu->adev->dev, "  .PPCLK_UCLK   = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_UCLK]);
2358         dev_info(smu->adev->dev, "  .PPCLK_FCLK   = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_FCLK]);
2359         dev_info(smu->adev->dev, "  .PPCLK_DCLK_0 = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_DCLK_0]);
2360         dev_info(smu->adev->dev, "  .PPCLK_VCLK_0 = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_VCLK_0]);
2361         dev_info(smu->adev->dev, "  .PPCLK_DCLK_1 = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_DCLK_1]);
2362         dev_info(smu->adev->dev, "  .PPCLK_VCLK_1 = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_VCLK_1]);
2363
2364         dev_info(smu->adev->dev, "FreqTableUclkDiv\n");
2365         for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2366                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->FreqTableUclkDiv[i]);
2367
2368         dev_info(smu->adev->dev, "FclkBoostFreq = 0x%x\n", pptable->FclkBoostFreq);
2369         dev_info(smu->adev->dev, "FclkParamPadding = 0x%x\n", pptable->FclkParamPadding);
2370
2371         dev_info(smu->adev->dev, "Mp0clkFreq\n");
2372         for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
2373                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->Mp0clkFreq[i]);
2374
2375         dev_info(smu->adev->dev, "Mp0DpmVoltage\n");
2376         for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
2377                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->Mp0DpmVoltage[i]);
2378
2379         dev_info(smu->adev->dev, "MemVddciVoltage\n");
2380         for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2381                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->MemVddciVoltage[i]);
2382
2383         dev_info(smu->adev->dev, "MemMvddVoltage\n");
2384         for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2385                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->MemMvddVoltage[i]);
2386
2387         dev_info(smu->adev->dev, "GfxclkFgfxoffEntry = 0x%x\n", pptable->GfxclkFgfxoffEntry);
2388         dev_info(smu->adev->dev, "GfxclkFinit = 0x%x\n", pptable->GfxclkFinit);
2389         dev_info(smu->adev->dev, "GfxclkFidle = 0x%x\n", pptable->GfxclkFidle);
2390         dev_info(smu->adev->dev, "GfxclkSource = 0x%x\n", pptable->GfxclkSource);
2391         dev_info(smu->adev->dev, "GfxclkPadding = 0x%x\n", pptable->GfxclkPadding);
2392
2393         dev_info(smu->adev->dev, "GfxGpoSubFeatureMask = 0x%x\n", pptable->GfxGpoSubFeatureMask);
2394
2395         dev_info(smu->adev->dev, "GfxGpoEnabledWorkPolicyMask = 0x%x\n", pptable->GfxGpoEnabledWorkPolicyMask);
2396         dev_info(smu->adev->dev, "GfxGpoDisabledWorkPolicyMask = 0x%x\n", pptable->GfxGpoDisabledWorkPolicyMask);
2397         dev_info(smu->adev->dev, "GfxGpoPadding[0] = 0x%x\n", pptable->GfxGpoPadding[0]);
2398         dev_info(smu->adev->dev, "GfxGpoVotingAllow = 0x%x\n", pptable->GfxGpoVotingAllow);
2399         dev_info(smu->adev->dev, "GfxGpoPadding32[0] = 0x%x\n", pptable->GfxGpoPadding32[0]);
2400         dev_info(smu->adev->dev, "GfxGpoPadding32[1] = 0x%x\n", pptable->GfxGpoPadding32[1]);
2401         dev_info(smu->adev->dev, "GfxGpoPadding32[2] = 0x%x\n", pptable->GfxGpoPadding32[2]);
2402         dev_info(smu->adev->dev, "GfxGpoPadding32[3] = 0x%x\n", pptable->GfxGpoPadding32[3]);
2403         dev_info(smu->adev->dev, "GfxDcsFopt = 0x%x\n", pptable->GfxDcsFopt);
2404         dev_info(smu->adev->dev, "GfxDcsFclkFopt = 0x%x\n", pptable->GfxDcsFclkFopt);
2405         dev_info(smu->adev->dev, "GfxDcsUclkFopt = 0x%x\n", pptable->GfxDcsUclkFopt);
2406
2407         dev_info(smu->adev->dev, "DcsGfxOffVoltage = 0x%x\n", pptable->DcsGfxOffVoltage);
2408         dev_info(smu->adev->dev, "DcsMinGfxOffTime = 0x%x\n", pptable->DcsMinGfxOffTime);
2409         dev_info(smu->adev->dev, "DcsMaxGfxOffTime = 0x%x\n", pptable->DcsMaxGfxOffTime);
2410         dev_info(smu->adev->dev, "DcsMinCreditAccum = 0x%x\n", pptable->DcsMinCreditAccum);
2411         dev_info(smu->adev->dev, "DcsExitHysteresis = 0x%x\n", pptable->DcsExitHysteresis);
2412         dev_info(smu->adev->dev, "DcsTimeout = 0x%x\n", pptable->DcsTimeout);
2413
2414         dev_info(smu->adev->dev, "DcsParamPadding[0] = 0x%x\n", pptable->DcsParamPadding[0]);
2415         dev_info(smu->adev->dev, "DcsParamPadding[1] = 0x%x\n", pptable->DcsParamPadding[1]);
2416         dev_info(smu->adev->dev, "DcsParamPadding[2] = 0x%x\n", pptable->DcsParamPadding[2]);
2417         dev_info(smu->adev->dev, "DcsParamPadding[3] = 0x%x\n", pptable->DcsParamPadding[3]);
2418         dev_info(smu->adev->dev, "DcsParamPadding[4] = 0x%x\n", pptable->DcsParamPadding[4]);
2419
2420         dev_info(smu->adev->dev, "FlopsPerByteTable\n");
2421         for (i = 0; i < RLC_PACE_TABLE_NUM_LEVELS; i++)
2422                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->FlopsPerByteTable[i]);
2423
2424         dev_info(smu->adev->dev, "LowestUclkReservedForUlv = 0x%x\n", pptable->LowestUclkReservedForUlv);
2425         dev_info(smu->adev->dev, "vddingMem[0] = 0x%x\n", pptable->PaddingMem[0]);
2426         dev_info(smu->adev->dev, "vddingMem[1] = 0x%x\n", pptable->PaddingMem[1]);
2427         dev_info(smu->adev->dev, "vddingMem[2] = 0x%x\n", pptable->PaddingMem[2]);
2428
2429         dev_info(smu->adev->dev, "UclkDpmPstates\n");
2430         for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
2431                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->UclkDpmPstates[i]);
2432
2433         dev_info(smu->adev->dev, "UclkDpmSrcFreqRange\n");
2434         dev_info(smu->adev->dev, "  .Fmin = 0x%x\n",
2435                 pptable->UclkDpmSrcFreqRange.Fmin);
2436         dev_info(smu->adev->dev, "  .Fmax = 0x%x\n",
2437                 pptable->UclkDpmSrcFreqRange.Fmax);
2438         dev_info(smu->adev->dev, "UclkDpmTargFreqRange\n");
2439         dev_info(smu->adev->dev, "  .Fmin = 0x%x\n",
2440                 pptable->UclkDpmTargFreqRange.Fmin);
2441         dev_info(smu->adev->dev, "  .Fmax = 0x%x\n",
2442                 pptable->UclkDpmTargFreqRange.Fmax);
2443         dev_info(smu->adev->dev, "UclkDpmMidstepFreq = 0x%x\n", pptable->UclkDpmMidstepFreq);
2444         dev_info(smu->adev->dev, "UclkMidstepPadding = 0x%x\n", pptable->UclkMidstepPadding);
2445
2446         dev_info(smu->adev->dev, "PcieGenSpeed\n");
2447         for (i = 0; i < NUM_LINK_LEVELS; i++)
2448                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->PcieGenSpeed[i]);
2449
2450         dev_info(smu->adev->dev, "PcieLaneCount\n");
2451         for (i = 0; i < NUM_LINK_LEVELS; i++)
2452                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->PcieLaneCount[i]);
2453
2454         dev_info(smu->adev->dev, "LclkFreq\n");
2455         for (i = 0; i < NUM_LINK_LEVELS; i++)
2456                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->LclkFreq[i]);
2457
2458         dev_info(smu->adev->dev, "FanStopTemp = 0x%x\n", pptable->FanStopTemp);
2459         dev_info(smu->adev->dev, "FanStartTemp = 0x%x\n", pptable->FanStartTemp);
2460
2461         dev_info(smu->adev->dev, "FanGain\n");
2462         for (i = 0; i < TEMP_COUNT; i++)
2463                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->FanGain[i]);
2464
2465         dev_info(smu->adev->dev, "FanPwmMin = 0x%x\n", pptable->FanPwmMin);
2466         dev_info(smu->adev->dev, "FanAcousticLimitRpm = 0x%x\n", pptable->FanAcousticLimitRpm);
2467         dev_info(smu->adev->dev, "FanThrottlingRpm = 0x%x\n", pptable->FanThrottlingRpm);
2468         dev_info(smu->adev->dev, "FanMaximumRpm = 0x%x\n", pptable->FanMaximumRpm);
2469         dev_info(smu->adev->dev, "MGpuFanBoostLimitRpm = 0x%x\n", pptable->MGpuFanBoostLimitRpm);
2470         dev_info(smu->adev->dev, "FanTargetTemperature = 0x%x\n", pptable->FanTargetTemperature);
2471         dev_info(smu->adev->dev, "FanTargetGfxclk = 0x%x\n", pptable->FanTargetGfxclk);
2472         dev_info(smu->adev->dev, "FanPadding16 = 0x%x\n", pptable->FanPadding16);
2473         dev_info(smu->adev->dev, "FanTempInputSelect = 0x%x\n", pptable->FanTempInputSelect);
2474         dev_info(smu->adev->dev, "FanPadding = 0x%x\n", pptable->FanPadding);
2475         dev_info(smu->adev->dev, "FanZeroRpmEnable = 0x%x\n", pptable->FanZeroRpmEnable);
2476         dev_info(smu->adev->dev, "FanTachEdgePerRev = 0x%x\n", pptable->FanTachEdgePerRev);
2477
2478         dev_info(smu->adev->dev, "FuzzyFan_ErrorSetDelta = 0x%x\n", pptable->FuzzyFan_ErrorSetDelta);
2479         dev_info(smu->adev->dev, "FuzzyFan_ErrorRateSetDelta = 0x%x\n", pptable->FuzzyFan_ErrorRateSetDelta);
2480         dev_info(smu->adev->dev, "FuzzyFan_PwmSetDelta = 0x%x\n", pptable->FuzzyFan_PwmSetDelta);
2481         dev_info(smu->adev->dev, "FuzzyFan_Reserved = 0x%x\n", pptable->FuzzyFan_Reserved);
2482
2483         dev_info(smu->adev->dev, "OverrideAvfsGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_GFX]);
2484         dev_info(smu->adev->dev, "OverrideAvfsGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_SOC]);
2485         dev_info(smu->adev->dev, "dBtcGbGfxDfllModelSelect = 0x%x\n", pptable->dBtcGbGfxDfllModelSelect);
2486         dev_info(smu->adev->dev, "Padding8_Avfs = 0x%x\n", pptable->Padding8_Avfs);
2487
2488         dev_info(smu->adev->dev, "qAvfsGb[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
2489                         pptable->qAvfsGb[AVFS_VOLTAGE_GFX].a,
2490                         pptable->qAvfsGb[AVFS_VOLTAGE_GFX].b,
2491                         pptable->qAvfsGb[AVFS_VOLTAGE_GFX].c);
2492         dev_info(smu->adev->dev, "qAvfsGb[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
2493                         pptable->qAvfsGb[AVFS_VOLTAGE_SOC].a,
2494                         pptable->qAvfsGb[AVFS_VOLTAGE_SOC].b,
2495                         pptable->qAvfsGb[AVFS_VOLTAGE_SOC].c);
2496         dev_info(smu->adev->dev, "dBtcGbGfxPll{a = 0x%x b = 0x%x c = 0x%x}\n",
2497                         pptable->dBtcGbGfxPll.a,
2498                         pptable->dBtcGbGfxPll.b,
2499                         pptable->dBtcGbGfxPll.c);
2500         dev_info(smu->adev->dev, "dBtcGbGfxAfll{a = 0x%x b = 0x%x c = 0x%x}\n",
2501                         pptable->dBtcGbGfxDfll.a,
2502                         pptable->dBtcGbGfxDfll.b,
2503                         pptable->dBtcGbGfxDfll.c);
2504         dev_info(smu->adev->dev, "dBtcGbSoc{a = 0x%x b = 0x%x c = 0x%x}\n",
2505                         pptable->dBtcGbSoc.a,
2506                         pptable->dBtcGbSoc.b,
2507                         pptable->dBtcGbSoc.c);
2508         dev_info(smu->adev->dev, "qAgingGb[AVFS_VOLTAGE_GFX]{m = 0x%x b = 0x%x}\n",
2509                         pptable->qAgingGb[AVFS_VOLTAGE_GFX].m,
2510                         pptable->qAgingGb[AVFS_VOLTAGE_GFX].b);
2511         dev_info(smu->adev->dev, "qAgingGb[AVFS_VOLTAGE_SOC]{m = 0x%x b = 0x%x}\n",
2512                         pptable->qAgingGb[AVFS_VOLTAGE_SOC].m,
2513                         pptable->qAgingGb[AVFS_VOLTAGE_SOC].b);
2514
2515         dev_info(smu->adev->dev, "PiecewiseLinearDroopIntGfxDfll\n");
2516         for (i = 0; i < NUM_PIECE_WISE_LINEAR_DROOP_MODEL_VF_POINTS; i++) {
2517                 dev_info(smu->adev->dev, "              Fset[%d] = 0x%x\n",
2518                         i, pptable->PiecewiseLinearDroopIntGfxDfll.Fset[i]);
2519                 dev_info(smu->adev->dev, "              Vdroop[%d] = 0x%x\n",
2520                         i, pptable->PiecewiseLinearDroopIntGfxDfll.Vdroop[i]);
2521         }
2522
2523         dev_info(smu->adev->dev, "qStaticVoltageOffset[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
2524                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].a,
2525                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].b,
2526                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].c);
2527         dev_info(smu->adev->dev, "qStaticVoltageOffset[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
2528                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].a,
2529                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].b,
2530                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].c);
2531
2532         dev_info(smu->adev->dev, "DcTol[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_GFX]);
2533         dev_info(smu->adev->dev, "DcTol[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_SOC]);
2534
2535         dev_info(smu->adev->dev, "DcBtcEnabled[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_GFX]);
2536         dev_info(smu->adev->dev, "DcBtcEnabled[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_SOC]);
2537         dev_info(smu->adev->dev, "Padding8_GfxBtc[0] = 0x%x\n", pptable->Padding8_GfxBtc[0]);
2538         dev_info(smu->adev->dev, "Padding8_GfxBtc[1] = 0x%x\n", pptable->Padding8_GfxBtc[1]);
2539
2540         dev_info(smu->adev->dev, "DcBtcMin[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_GFX]);
2541         dev_info(smu->adev->dev, "DcBtcMin[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_SOC]);
2542         dev_info(smu->adev->dev, "DcBtcMax[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_GFX]);
2543         dev_info(smu->adev->dev, "DcBtcMax[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_SOC]);
2544
2545         dev_info(smu->adev->dev, "DcBtcGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_GFX]);
2546         dev_info(smu->adev->dev, "DcBtcGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_SOC]);
2547
2548         dev_info(smu->adev->dev, "XgmiDpmPstates\n");
2549         for (i = 0; i < NUM_XGMI_LEVELS; i++)
2550                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiDpmPstates[i]);
2551         dev_info(smu->adev->dev, "XgmiDpmSpare[0] = 0x%02x\n", pptable->XgmiDpmSpare[0]);
2552         dev_info(smu->adev->dev, "XgmiDpmSpare[1] = 0x%02x\n", pptable->XgmiDpmSpare[1]);
2553
2554         dev_info(smu->adev->dev, "DebugOverrides = 0x%x\n", pptable->DebugOverrides);
2555         dev_info(smu->adev->dev, "ReservedEquation0{a = 0x%x b = 0x%x c = 0x%x}\n",
2556                         pptable->ReservedEquation0.a,
2557                         pptable->ReservedEquation0.b,
2558                         pptable->ReservedEquation0.c);
2559         dev_info(smu->adev->dev, "ReservedEquation1{a = 0x%x b = 0x%x c = 0x%x}\n",
2560                         pptable->ReservedEquation1.a,
2561                         pptable->ReservedEquation1.b,
2562                         pptable->ReservedEquation1.c);
2563         dev_info(smu->adev->dev, "ReservedEquation2{a = 0x%x b = 0x%x c = 0x%x}\n",
2564                         pptable->ReservedEquation2.a,
2565                         pptable->ReservedEquation2.b,
2566                         pptable->ReservedEquation2.c);
2567         dev_info(smu->adev->dev, "ReservedEquation3{a = 0x%x b = 0x%x c = 0x%x}\n",
2568                         pptable->ReservedEquation3.a,
2569                         pptable->ReservedEquation3.b,
2570                         pptable->ReservedEquation3.c);
2571
2572         dev_info(smu->adev->dev, "SkuReserved[0] = 0x%x\n", pptable->SkuReserved[0]);
2573         dev_info(smu->adev->dev, "SkuReserved[1] = 0x%x\n", pptable->SkuReserved[1]);
2574         dev_info(smu->adev->dev, "SkuReserved[2] = 0x%x\n", pptable->SkuReserved[2]);
2575         dev_info(smu->adev->dev, "SkuReserved[3] = 0x%x\n", pptable->SkuReserved[3]);
2576         dev_info(smu->adev->dev, "SkuReserved[4] = 0x%x\n", pptable->SkuReserved[4]);
2577         dev_info(smu->adev->dev, "SkuReserved[5] = 0x%x\n", pptable->SkuReserved[5]);
2578         dev_info(smu->adev->dev, "SkuReserved[6] = 0x%x\n", pptable->SkuReserved[6]);
2579         dev_info(smu->adev->dev, "SkuReserved[7] = 0x%x\n", pptable->SkuReserved[7]);
2580
2581         dev_info(smu->adev->dev, "GamingClk[0] = 0x%x\n", pptable->GamingClk[0]);
2582         dev_info(smu->adev->dev, "GamingClk[1] = 0x%x\n", pptable->GamingClk[1]);
2583         dev_info(smu->adev->dev, "GamingClk[2] = 0x%x\n", pptable->GamingClk[2]);
2584         dev_info(smu->adev->dev, "GamingClk[3] = 0x%x\n", pptable->GamingClk[3]);
2585         dev_info(smu->adev->dev, "GamingClk[4] = 0x%x\n", pptable->GamingClk[4]);
2586         dev_info(smu->adev->dev, "GamingClk[5] = 0x%x\n", pptable->GamingClk[5]);
2587
2588         for (i = 0; i < NUM_I2C_CONTROLLERS; i++) {
2589                 dev_info(smu->adev->dev, "I2cControllers[%d]:\n", i);
2590                 dev_info(smu->adev->dev, "                   .Enabled = 0x%x\n",
2591                                 pptable->I2cControllers[i].Enabled);
2592                 dev_info(smu->adev->dev, "                   .Speed = 0x%x\n",
2593                                 pptable->I2cControllers[i].Speed);
2594                 dev_info(smu->adev->dev, "                   .SlaveAddress = 0x%x\n",
2595                                 pptable->I2cControllers[i].SlaveAddress);
2596                 dev_info(smu->adev->dev, "                   .ControllerPort = 0x%x\n",
2597                                 pptable->I2cControllers[i].ControllerPort);
2598                 dev_info(smu->adev->dev, "                   .ControllerName = 0x%x\n",
2599                                 pptable->I2cControllers[i].ControllerName);
2600                 dev_info(smu->adev->dev, "                   .ThermalThrottler = 0x%x\n",
2601                                 pptable->I2cControllers[i].ThermalThrotter);
2602                 dev_info(smu->adev->dev, "                   .I2cProtocol = 0x%x\n",
2603                                 pptable->I2cControllers[i].I2cProtocol);
2604                 dev_info(smu->adev->dev, "                   .PaddingConfig = 0x%x\n",
2605                                 pptable->I2cControllers[i].PaddingConfig);
2606         }
2607
2608         dev_info(smu->adev->dev, "GpioScl = 0x%x\n", pptable->GpioScl);
2609         dev_info(smu->adev->dev, "GpioSda = 0x%x\n", pptable->GpioSda);
2610         dev_info(smu->adev->dev, "FchUsbPdSlaveAddr = 0x%x\n", pptable->FchUsbPdSlaveAddr);
2611         dev_info(smu->adev->dev, "I2cSpare[0] = 0x%x\n", pptable->I2cSpare[0]);
2612
2613         dev_info(smu->adev->dev, "Board Parameters:\n");
2614         dev_info(smu->adev->dev, "VddGfxVrMapping = 0x%x\n", pptable->VddGfxVrMapping);
2615         dev_info(smu->adev->dev, "VddSocVrMapping = 0x%x\n", pptable->VddSocVrMapping);
2616         dev_info(smu->adev->dev, "VddMem0VrMapping = 0x%x\n", pptable->VddMem0VrMapping);
2617         dev_info(smu->adev->dev, "VddMem1VrMapping = 0x%x\n", pptable->VddMem1VrMapping);
2618         dev_info(smu->adev->dev, "GfxUlvPhaseSheddingMask = 0x%x\n", pptable->GfxUlvPhaseSheddingMask);
2619         dev_info(smu->adev->dev, "SocUlvPhaseSheddingMask = 0x%x\n", pptable->SocUlvPhaseSheddingMask);
2620         dev_info(smu->adev->dev, "VddciUlvPhaseSheddingMask = 0x%x\n", pptable->VddciUlvPhaseSheddingMask);
2621         dev_info(smu->adev->dev, "MvddUlvPhaseSheddingMask = 0x%x\n", pptable->MvddUlvPhaseSheddingMask);
2622
2623         dev_info(smu->adev->dev, "GfxMaxCurrent = 0x%x\n", pptable->GfxMaxCurrent);
2624         dev_info(smu->adev->dev, "GfxOffset = 0x%x\n", pptable->GfxOffset);
2625         dev_info(smu->adev->dev, "Padding_TelemetryGfx = 0x%x\n", pptable->Padding_TelemetryGfx);
2626
2627         dev_info(smu->adev->dev, "SocMaxCurrent = 0x%x\n", pptable->SocMaxCurrent);
2628         dev_info(smu->adev->dev, "SocOffset = 0x%x\n", pptable->SocOffset);
2629         dev_info(smu->adev->dev, "Padding_TelemetrySoc = 0x%x\n", pptable->Padding_TelemetrySoc);
2630
2631         dev_info(smu->adev->dev, "Mem0MaxCurrent = 0x%x\n", pptable->Mem0MaxCurrent);
2632         dev_info(smu->adev->dev, "Mem0Offset = 0x%x\n", pptable->Mem0Offset);
2633         dev_info(smu->adev->dev, "Padding_TelemetryMem0 = 0x%x\n", pptable->Padding_TelemetryMem0);
2634
2635         dev_info(smu->adev->dev, "Mem1MaxCurrent = 0x%x\n", pptable->Mem1MaxCurrent);
2636         dev_info(smu->adev->dev, "Mem1Offset = 0x%x\n", pptable->Mem1Offset);
2637         dev_info(smu->adev->dev, "Padding_TelemetryMem1 = 0x%x\n", pptable->Padding_TelemetryMem1);
2638
2639         dev_info(smu->adev->dev, "MvddRatio = 0x%x\n", pptable->MvddRatio);
2640
2641         dev_info(smu->adev->dev, "AcDcGpio = 0x%x\n", pptable->AcDcGpio);
2642         dev_info(smu->adev->dev, "AcDcPolarity = 0x%x\n", pptable->AcDcPolarity);
2643         dev_info(smu->adev->dev, "VR0HotGpio = 0x%x\n", pptable->VR0HotGpio);
2644         dev_info(smu->adev->dev, "VR0HotPolarity = 0x%x\n", pptable->VR0HotPolarity);
2645         dev_info(smu->adev->dev, "VR1HotGpio = 0x%x\n", pptable->VR1HotGpio);
2646         dev_info(smu->adev->dev, "VR1HotPolarity = 0x%x\n", pptable->VR1HotPolarity);
2647         dev_info(smu->adev->dev, "GthrGpio = 0x%x\n", pptable->GthrGpio);
2648         dev_info(smu->adev->dev, "GthrPolarity = 0x%x\n", pptable->GthrPolarity);
2649         dev_info(smu->adev->dev, "LedPin0 = 0x%x\n", pptable->LedPin0);
2650         dev_info(smu->adev->dev, "LedPin1 = 0x%x\n", pptable->LedPin1);
2651         dev_info(smu->adev->dev, "LedPin2 = 0x%x\n", pptable->LedPin2);
2652         dev_info(smu->adev->dev, "LedEnableMask = 0x%x\n", pptable->LedEnableMask);
2653         dev_info(smu->adev->dev, "LedPcie = 0x%x\n", pptable->LedPcie);
2654         dev_info(smu->adev->dev, "LedError = 0x%x\n", pptable->LedError);
2655         dev_info(smu->adev->dev, "LedSpare1[0] = 0x%x\n", pptable->LedSpare1[0]);
2656         dev_info(smu->adev->dev, "LedSpare1[1] = 0x%x\n", pptable->LedSpare1[1]);
2657
2658         dev_info(smu->adev->dev, "PllGfxclkSpreadEnabled = 0x%x\n", pptable->PllGfxclkSpreadEnabled);
2659         dev_info(smu->adev->dev, "PllGfxclkSpreadPercent = 0x%x\n", pptable->PllGfxclkSpreadPercent);
2660         dev_info(smu->adev->dev, "PllGfxclkSpreadFreq = 0x%x\n",    pptable->PllGfxclkSpreadFreq);
2661
2662         dev_info(smu->adev->dev, "DfllGfxclkSpreadEnabled = 0x%x\n", pptable->DfllGfxclkSpreadEnabled);
2663         dev_info(smu->adev->dev, "DfllGfxclkSpreadPercent = 0x%x\n", pptable->DfllGfxclkSpreadPercent);
2664         dev_info(smu->adev->dev, "DfllGfxclkSpreadFreq = 0x%x\n",    pptable->DfllGfxclkSpreadFreq);
2665
2666         dev_info(smu->adev->dev, "UclkSpreadPadding = 0x%x\n", pptable->UclkSpreadPadding);
2667         dev_info(smu->adev->dev, "UclkSpreadFreq = 0x%x\n", pptable->UclkSpreadFreq);
2668
2669         dev_info(smu->adev->dev, "FclkSpreadEnabled = 0x%x\n", pptable->FclkSpreadEnabled);
2670         dev_info(smu->adev->dev, "FclkSpreadPercent = 0x%x\n", pptable->FclkSpreadPercent);
2671         dev_info(smu->adev->dev, "FclkSpreadFreq = 0x%x\n", pptable->FclkSpreadFreq);
2672
2673         dev_info(smu->adev->dev, "MemoryChannelEnabled = 0x%x\n", pptable->MemoryChannelEnabled);
2674         dev_info(smu->adev->dev, "DramBitWidth = 0x%x\n", pptable->DramBitWidth);
2675         dev_info(smu->adev->dev, "PaddingMem1[0] = 0x%x\n", pptable->PaddingMem1[0]);
2676         dev_info(smu->adev->dev, "PaddingMem1[1] = 0x%x\n", pptable->PaddingMem1[1]);
2677         dev_info(smu->adev->dev, "PaddingMem1[2] = 0x%x\n", pptable->PaddingMem1[2]);
2678
2679         dev_info(smu->adev->dev, "TotalBoardPower = 0x%x\n", pptable->TotalBoardPower);
2680         dev_info(smu->adev->dev, "BoardPowerPadding = 0x%x\n", pptable->BoardPowerPadding);
2681
2682         dev_info(smu->adev->dev, "XgmiLinkSpeed\n");
2683         for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
2684                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiLinkSpeed[i]);
2685         dev_info(smu->adev->dev, "XgmiLinkWidth\n");
2686         for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
2687                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiLinkWidth[i]);
2688         dev_info(smu->adev->dev, "XgmiFclkFreq\n");
2689         for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
2690                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiFclkFreq[i]);
2691         dev_info(smu->adev->dev, "XgmiSocVoltage\n");
2692         for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
2693                 dev_info(smu->adev->dev, "  .[%d] = 0x%x\n", i, pptable->XgmiSocVoltage[i]);
2694
2695         dev_info(smu->adev->dev, "HsrEnabled = 0x%x\n", pptable->HsrEnabled);
2696         dev_info(smu->adev->dev, "VddqOffEnabled = 0x%x\n", pptable->VddqOffEnabled);
2697         dev_info(smu->adev->dev, "PaddingUmcFlags[0] = 0x%x\n", pptable->PaddingUmcFlags[0]);
2698         dev_info(smu->adev->dev, "PaddingUmcFlags[1] = 0x%x\n", pptable->PaddingUmcFlags[1]);
2699
2700         dev_info(smu->adev->dev, "BoardReserved[0] = 0x%x\n", pptable->BoardReserved[0]);
2701         dev_info(smu->adev->dev, "BoardReserved[1] = 0x%x\n", pptable->BoardReserved[1]);
2702         dev_info(smu->adev->dev, "BoardReserved[2] = 0x%x\n", pptable->BoardReserved[2]);
2703         dev_info(smu->adev->dev, "BoardReserved[3] = 0x%x\n", pptable->BoardReserved[3]);
2704         dev_info(smu->adev->dev, "BoardReserved[4] = 0x%x\n", pptable->BoardReserved[4]);
2705         dev_info(smu->adev->dev, "BoardReserved[5] = 0x%x\n", pptable->BoardReserved[5]);
2706         dev_info(smu->adev->dev, "BoardReserved[6] = 0x%x\n", pptable->BoardReserved[6]);
2707         dev_info(smu->adev->dev, "BoardReserved[7] = 0x%x\n", pptable->BoardReserved[7]);
2708         dev_info(smu->adev->dev, "BoardReserved[8] = 0x%x\n", pptable->BoardReserved[8]);
2709         dev_info(smu->adev->dev, "BoardReserved[9] = 0x%x\n", pptable->BoardReserved[9]);
2710         dev_info(smu->adev->dev, "BoardReserved[10] = 0x%x\n", pptable->BoardReserved[10]);
2711
2712         dev_info(smu->adev->dev, "MmHubPadding[0] = 0x%x\n", pptable->MmHubPadding[0]);
2713         dev_info(smu->adev->dev, "MmHubPadding[1] = 0x%x\n", pptable->MmHubPadding[1]);
2714         dev_info(smu->adev->dev, "MmHubPadding[2] = 0x%x\n", pptable->MmHubPadding[2]);
2715         dev_info(smu->adev->dev, "MmHubPadding[3] = 0x%x\n", pptable->MmHubPadding[3]);
2716         dev_info(smu->adev->dev, "MmHubPadding[4] = 0x%x\n", pptable->MmHubPadding[4]);
2717         dev_info(smu->adev->dev, "MmHubPadding[5] = 0x%x\n", pptable->MmHubPadding[5]);
2718         dev_info(smu->adev->dev, "MmHubPadding[6] = 0x%x\n", pptable->MmHubPadding[6]);
2719         dev_info(smu->adev->dev, "MmHubPadding[7] = 0x%x\n", pptable->MmHubPadding[7]);
2720 }
2721
2722 static void sienna_cichlid_fill_i2c_req(SwI2cRequest_t  *req, bool write,
2723                                   uint8_t address, uint32_t numbytes,
2724                                   uint8_t *data)
2725 {
2726         int i;
2727
2728         req->I2CcontrollerPort = 1;
2729         req->I2CSpeed = 2;
2730         req->SlaveAddress = address;
2731         req->NumCmds = numbytes;
2732
2733         for (i = 0; i < numbytes; i++) {
2734                 SwI2cCmd_t *cmd =  &req->SwI2cCmds[i];
2735
2736                 /* First 2 bytes are always write for lower 2b EEPROM address */
2737                 if (i < 2)
2738                         cmd->CmdConfig = CMDCONFIG_READWRITE_MASK;
2739                 else
2740                         cmd->CmdConfig = write ? CMDCONFIG_READWRITE_MASK : 0;
2741
2742
2743                 /* Add RESTART for read  after address filled */
2744                 cmd->CmdConfig |= (i == 2 && !write) ? CMDCONFIG_RESTART_MASK : 0;
2745
2746                 /* Add STOP in the end */
2747                 cmd->CmdConfig |= (i == (numbytes - 1)) ? CMDCONFIG_STOP_MASK : 0;
2748
2749                 /* Fill with data regardless if read or write to simplify code */
2750                 cmd->ReadWriteData = data[i];
2751         }
2752 }
2753
2754 static int sienna_cichlid_i2c_read_data(struct i2c_adapter *control,
2755                                                uint8_t address,
2756                                                uint8_t *data,
2757                                                uint32_t numbytes)
2758 {
2759         uint32_t  i, ret = 0;
2760         SwI2cRequest_t req;
2761         struct amdgpu_device *adev = to_amdgpu_device(control);
2762         struct smu_table_context *smu_table = &adev->smu.smu_table;
2763         struct smu_table *table = &smu_table->driver_table;
2764
2765         if (numbytes > MAX_SW_I2C_COMMANDS) {
2766                 dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
2767                         numbytes, MAX_SW_I2C_COMMANDS);
2768                 return -EINVAL;
2769         }
2770
2771         memset(&req, 0, sizeof(req));
2772         sienna_cichlid_fill_i2c_req(&req, false, address, numbytes, data);
2773
2774         mutex_lock(&adev->smu.mutex);
2775         /* Now read data starting with that address */
2776         ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req,
2777                                         true);
2778         mutex_unlock(&adev->smu.mutex);
2779
2780         if (!ret) {
2781                 SwI2cRequest_t *res = (SwI2cRequest_t *)table->cpu_addr;
2782
2783                 /* Assume SMU  fills res.SwI2cCmds[i].Data with read bytes */
2784                 for (i = 0; i < numbytes; i++)
2785                         data[i] = res->SwI2cCmds[i].ReadWriteData;
2786
2787                 dev_dbg(adev->dev, "sienna_cichlid_i2c_read_data, address = %x, bytes = %d, data :",
2788                                   (uint16_t)address, numbytes);
2789
2790                 print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
2791                                8, 1, data, numbytes, false);
2792         } else
2793                 dev_err(adev->dev, "sienna_cichlid_i2c_read_data - error occurred :%x", ret);
2794
2795         return ret;
2796 }
2797
2798 static int sienna_cichlid_i2c_write_data(struct i2c_adapter *control,
2799                                                 uint8_t address,
2800                                                 uint8_t *data,
2801                                                 uint32_t numbytes)
2802 {
2803         uint32_t ret;
2804         SwI2cRequest_t req;
2805         struct amdgpu_device *adev = to_amdgpu_device(control);
2806
2807         if (numbytes > MAX_SW_I2C_COMMANDS) {
2808                 dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
2809                         numbytes, MAX_SW_I2C_COMMANDS);
2810                 return -EINVAL;
2811         }
2812
2813         memset(&req, 0, sizeof(req));
2814         sienna_cichlid_fill_i2c_req(&req, true, address, numbytes, data);
2815
2816         mutex_lock(&adev->smu.mutex);
2817         ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req, true);
2818         mutex_unlock(&adev->smu.mutex);
2819
2820         if (!ret) {
2821                 dev_dbg(adev->dev, "sienna_cichlid_i2c_write(), address = %x, bytes = %d , data: ",
2822                                          (uint16_t)address, numbytes);
2823
2824                 print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
2825                                8, 1, data, numbytes, false);
2826                 /*
2827                  * According to EEPROM spec there is a MAX of 10 ms required for
2828                  * EEPROM to flush internal RX buffer after STOP was issued at the
2829                  * end of write transaction. During this time the EEPROM will not be
2830                  * responsive to any more commands - so wait a bit more.
2831                  */
2832                 msleep(10);
2833
2834         } else
2835                 dev_err(adev->dev, "sienna_cichlid_i2c_write- error occurred :%x", ret);
2836
2837         return ret;
2838 }
2839
2840 static int sienna_cichlid_i2c_xfer(struct i2c_adapter *i2c_adap,
2841                               struct i2c_msg *msgs, int num)
2842 {
2843         uint32_t  i, j, ret, data_size, data_chunk_size, next_eeprom_addr = 0;
2844         uint8_t *data_ptr, data_chunk[MAX_SW_I2C_COMMANDS] = { 0 };
2845
2846         for (i = 0; i < num; i++) {
2847                 /*
2848                  * SMU interface allows at most MAX_SW_I2C_COMMANDS bytes of data at
2849                  * once and hence the data needs to be spliced into chunks and sent each
2850                  * chunk separately
2851                  */
2852                 data_size = msgs[i].len - 2;
2853                 data_chunk_size = MAX_SW_I2C_COMMANDS - 2;
2854                 next_eeprom_addr = (msgs[i].buf[0] << 8 & 0xff00) | (msgs[i].buf[1] & 0xff);
2855                 data_ptr = msgs[i].buf + 2;
2856
2857                 for (j = 0; j < data_size / data_chunk_size; j++) {
2858                         /* Insert the EEPROM dest addess, bits 0-15 */
2859                         data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2860                         data_chunk[1] = (next_eeprom_addr & 0xff);
2861
2862                         if (msgs[i].flags & I2C_M_RD) {
2863                                 ret = sienna_cichlid_i2c_read_data(i2c_adap,
2864                                                              (uint8_t)msgs[i].addr,
2865                                                              data_chunk, MAX_SW_I2C_COMMANDS);
2866
2867                                 memcpy(data_ptr, data_chunk + 2, data_chunk_size);
2868                         } else {
2869
2870                                 memcpy(data_chunk + 2, data_ptr, data_chunk_size);
2871
2872                                 ret = sienna_cichlid_i2c_write_data(i2c_adap,
2873                                                               (uint8_t)msgs[i].addr,
2874                                                               data_chunk, MAX_SW_I2C_COMMANDS);
2875                         }
2876
2877                         if (ret) {
2878                                 num = -EIO;
2879                                 goto fail;
2880                         }
2881
2882                         next_eeprom_addr += data_chunk_size;
2883                         data_ptr += data_chunk_size;
2884                 }
2885
2886                 if (data_size % data_chunk_size) {
2887                         data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2888                         data_chunk[1] = (next_eeprom_addr & 0xff);
2889
2890                         if (msgs[i].flags & I2C_M_RD) {
2891                                 ret = sienna_cichlid_i2c_read_data(i2c_adap,
2892                                                              (uint8_t)msgs[i].addr,
2893                                                              data_chunk, (data_size % data_chunk_size) + 2);
2894
2895                                 memcpy(data_ptr, data_chunk + 2, data_size % data_chunk_size);
2896                         } else {
2897                                 memcpy(data_chunk + 2, data_ptr, data_size % data_chunk_size);
2898
2899                                 ret = sienna_cichlid_i2c_write_data(i2c_adap,
2900                                                               (uint8_t)msgs[i].addr,
2901                                                               data_chunk, (data_size % data_chunk_size) + 2);
2902                         }
2903
2904                         if (ret) {
2905                                 num = -EIO;
2906                                 goto fail;
2907                         }
2908                 }
2909         }
2910
2911 fail:
2912         return num;
2913 }
2914
2915 static u32 sienna_cichlid_i2c_func(struct i2c_adapter *adap)
2916 {
2917         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
2918 }
2919
2920
2921 static const struct i2c_algorithm sienna_cichlid_i2c_algo = {
2922         .master_xfer = sienna_cichlid_i2c_xfer,
2923         .functionality = sienna_cichlid_i2c_func,
2924 };
2925
2926 static int sienna_cichlid_i2c_control_init(struct smu_context *smu, struct i2c_adapter *control)
2927 {
2928         struct amdgpu_device *adev = to_amdgpu_device(control);
2929         int res;
2930
2931         control->owner = THIS_MODULE;
2932         control->class = I2C_CLASS_SPD;
2933         control->dev.parent = &adev->pdev->dev;
2934         control->algo = &sienna_cichlid_i2c_algo;
2935         snprintf(control->name, sizeof(control->name), "AMDGPU SMU");
2936
2937         res = i2c_add_adapter(control);
2938         if (res)
2939                 DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
2940
2941         return res;
2942 }
2943
2944 static void sienna_cichlid_i2c_control_fini(struct smu_context *smu, struct i2c_adapter *control)
2945 {
2946         i2c_del_adapter(control);
2947 }
2948
2949 static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu,
2950                                               void **table)
2951 {
2952         struct smu_table_context *smu_table = &smu->smu_table;
2953         struct gpu_metrics_v1_1 *gpu_metrics =
2954                 (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table;
2955         SmuMetricsExternal_t metrics_external;
2956         SmuMetrics_t *metrics =
2957                 &(metrics_external.SmuMetrics);
2958         struct amdgpu_device *adev = smu->adev;
2959         uint32_t smu_version;
2960         int ret = 0;
2961
2962         ret = smu_cmn_get_metrics_table(smu,
2963                                         &metrics_external,
2964                                         true);
2965         if (ret)
2966                 return ret;
2967
2968         smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1);
2969
2970         gpu_metrics->temperature_edge = metrics->TemperatureEdge;
2971         gpu_metrics->temperature_hotspot = metrics->TemperatureHotspot;
2972         gpu_metrics->temperature_mem = metrics->TemperatureMem;
2973         gpu_metrics->temperature_vrgfx = metrics->TemperatureVrGfx;
2974         gpu_metrics->temperature_vrsoc = metrics->TemperatureVrSoc;
2975         gpu_metrics->temperature_vrmem = metrics->TemperatureVrMem0;
2976
2977         gpu_metrics->average_gfx_activity = metrics->AverageGfxActivity;
2978         gpu_metrics->average_umc_activity = metrics->AverageUclkActivity;
2979         gpu_metrics->average_mm_activity = metrics->VcnActivityPercentage;
2980
2981         gpu_metrics->average_socket_power = metrics->AverageSocketPower;
2982         gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
2983
2984         if (metrics->AverageGfxActivity <= SMU_11_0_7_GFX_BUSY_THRESHOLD)
2985                 gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
2986         else
2987                 gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPreDs;
2988         gpu_metrics->average_uclk_frequency = metrics->AverageUclkFrequencyPostDs;
2989         gpu_metrics->average_vclk0_frequency = metrics->AverageVclk0Frequency;
2990         gpu_metrics->average_dclk0_frequency = metrics->AverageDclk0Frequency;
2991         gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency;
2992         gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency;
2993
2994         gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK];
2995         gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK];
2996         gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK];
2997         gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0];
2998         gpu_metrics->current_dclk0 = metrics->CurrClock[PPCLK_DCLK_0];
2999         gpu_metrics->current_vclk1 = metrics->CurrClock[PPCLK_VCLK_1];
3000         gpu_metrics->current_dclk1 = metrics->CurrClock[PPCLK_DCLK_1];
3001
3002         gpu_metrics->throttle_status = metrics->ThrottlerStatus;
3003
3004         gpu_metrics->current_fan_speed = metrics->CurrFanSpeed;
3005
3006         ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
3007         if (ret)
3008                 return ret;
3009
3010         if (((adev->asic_type == CHIP_SIENNA_CICHLID) && smu_version > 0x003A1E00) ||
3011               ((adev->asic_type == CHIP_NAVY_FLOUNDER) && smu_version > 0x00410400)) {
3012                 gpu_metrics->pcie_link_width = metrics->PcieWidth;
3013                 gpu_metrics->pcie_link_speed = link_speed[metrics->PcieRate];
3014         } else {
3015                 gpu_metrics->pcie_link_width =
3016                                 smu_v11_0_get_current_pcie_link_width(smu);
3017                 gpu_metrics->pcie_link_speed =
3018                                 smu_v11_0_get_current_pcie_link_speed(smu);
3019         }
3020
3021         gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
3022
3023         *table = (void *)gpu_metrics;
3024
3025         return sizeof(struct gpu_metrics_v1_1);
3026 }
3027
3028 static int sienna_cichlid_enable_mgpu_fan_boost(struct smu_context *smu)
3029 {
3030         struct smu_table_context *table_context = &smu->smu_table;
3031         PPTable_t *smc_pptable = table_context->driver_pptable;
3032
3033         /*
3034          * Skip the MGpuFanBoost setting for those ASICs
3035          * which do not support it
3036          */
3037         if (!smc_pptable->MGpuFanBoostLimitRpm)
3038                 return 0;
3039
3040         return smu_cmn_send_smc_msg_with_param(smu,
3041                                                SMU_MSG_SetMGpuFanBoostLimitRpm,
3042                                                0,
3043                                                NULL);
3044 }
3045
3046 static int sienna_cichlid_gpo_control(struct smu_context *smu,
3047                                       bool enablement)
3048 {
3049         uint32_t smu_version;
3050         int ret = 0;
3051
3052
3053         if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_GFX_GPO_BIT)) {
3054                 ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
3055                 if (ret)
3056                         return ret;
3057
3058                 if (enablement) {
3059                         if (smu_version < 0x003a2500) {
3060                                 ret = smu_cmn_send_smc_msg_with_param(smu,
3061                                                                       SMU_MSG_SetGpoFeaturePMask,
3062                                                                       GFX_GPO_PACE_MASK | GFX_GPO_DEM_MASK,
3063                                                                       NULL);
3064                         } else {
3065                                 ret = smu_cmn_send_smc_msg_with_param(smu,
3066                                                                       SMU_MSG_DisallowGpo,
3067                                                                       0,
3068                                                                       NULL);
3069                         }
3070                 } else {
3071                         if (smu_version < 0x003a2500) {
3072                                 ret = smu_cmn_send_smc_msg_with_param(smu,
3073                                                                       SMU_MSG_SetGpoFeaturePMask,
3074                                                                       0,
3075                                                                       NULL);
3076                         } else {
3077                                 ret = smu_cmn_send_smc_msg_with_param(smu,
3078                                                                       SMU_MSG_DisallowGpo,
3079                                                                       1,
3080                                                                       NULL);
3081                         }
3082                 }
3083         }
3084
3085         return ret;
3086 }
3087
3088 static int sienna_cichlid_notify_2nd_usb20_port(struct smu_context *smu)
3089 {
3090         uint32_t smu_version;
3091         int ret = 0;
3092
3093         ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
3094         if (ret)
3095                 return ret;
3096
3097         /*
3098          * Message SMU_MSG_Enable2ndUSB20Port is supported by 58.45
3099          * onwards PMFWs.
3100          */
3101         if (smu_version < 0x003A2D00)
3102                 return 0;
3103
3104         return smu_cmn_send_smc_msg_with_param(smu,
3105                                                SMU_MSG_Enable2ndUSB20Port,
3106                                                smu->smu_table.boot_values.firmware_caps & ATOM_FIRMWARE_CAP_ENABLE_2ND_USB20PORT ?
3107                                                1 : 0,
3108                                                NULL);
3109 }
3110
3111 static int sienna_cichlid_system_features_control(struct smu_context *smu,
3112                                                   bool en)
3113 {
3114         int ret = 0;
3115
3116         if (en) {
3117                 ret = sienna_cichlid_notify_2nd_usb20_port(smu);
3118                 if (ret)
3119                         return ret;
3120         }
3121
3122         return smu_v11_0_system_features_control(smu, en);
3123 }
3124
3125 static int sienna_cichlid_set_mp1_state(struct smu_context *smu,
3126                                         enum pp_mp1_state mp1_state)
3127 {
3128         int ret;
3129
3130         switch (mp1_state) {
3131         case PP_MP1_STATE_UNLOAD:
3132                 ret = smu_cmn_set_mp1_state(smu, mp1_state);
3133                 break;
3134         default:
3135                 /* Ignore others */
3136                 ret = 0;
3137         }
3138
3139         return ret;
3140 }
3141
3142 static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
3143         .get_allowed_feature_mask = sienna_cichlid_get_allowed_feature_mask,
3144         .set_default_dpm_table = sienna_cichlid_set_default_dpm_table,
3145         .dpm_set_vcn_enable = sienna_cichlid_dpm_set_vcn_enable,
3146         .dpm_set_jpeg_enable = sienna_cichlid_dpm_set_jpeg_enable,
3147         .i2c_init = sienna_cichlid_i2c_control_init,
3148         .i2c_fini = sienna_cichlid_i2c_control_fini,
3149         .print_clk_levels = sienna_cichlid_print_clk_levels,
3150         .force_clk_levels = sienna_cichlid_force_clk_levels,
3151         .populate_umd_state_clk = sienna_cichlid_populate_umd_state_clk,
3152         .pre_display_config_changed = sienna_cichlid_pre_display_config_changed,
3153         .display_config_changed = sienna_cichlid_display_config_changed,
3154         .notify_smc_display_config = sienna_cichlid_notify_smc_display_config,
3155         .is_dpm_running = sienna_cichlid_is_dpm_running,
3156         .get_fan_speed_percent = sienna_cichlid_get_fan_speed_percent,
3157         .get_power_profile_mode = sienna_cichlid_get_power_profile_mode,
3158         .set_power_profile_mode = sienna_cichlid_set_power_profile_mode,
3159         .set_watermarks_table = sienna_cichlid_set_watermarks_table,
3160         .read_sensor = sienna_cichlid_read_sensor,
3161         .get_uclk_dpm_states = sienna_cichlid_get_uclk_dpm_states,
3162         .set_performance_level = smu_v11_0_set_performance_level,
3163         .get_thermal_temperature_range = sienna_cichlid_get_thermal_temperature_range,
3164         .display_disable_memory_clock_switch = sienna_cichlid_display_disable_memory_clock_switch,
3165         .get_power_limit = sienna_cichlid_get_power_limit,
3166         .update_pcie_parameters = sienna_cichlid_update_pcie_parameters,
3167         .dump_pptable = sienna_cichlid_dump_pptable,
3168         .init_microcode = smu_v11_0_init_microcode,
3169         .load_microcode = smu_v11_0_load_microcode,
3170         .init_smc_tables = sienna_cichlid_init_smc_tables,
3171         .fini_smc_tables = smu_v11_0_fini_smc_tables,
3172         .init_power = smu_v11_0_init_power,
3173         .fini_power = smu_v11_0_fini_power,
3174         .check_fw_status = smu_v11_0_check_fw_status,
3175         .setup_pptable = sienna_cichlid_setup_pptable,
3176         .get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
3177         .check_fw_version = smu_v11_0_check_fw_version,
3178         .write_pptable = smu_cmn_write_pptable,
3179         .set_driver_table_location = smu_v11_0_set_driver_table_location,
3180         .set_tool_table_location = smu_v11_0_set_tool_table_location,
3181         .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
3182         .system_features_control = sienna_cichlid_system_features_control,
3183         .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
3184         .send_smc_msg = smu_cmn_send_smc_msg,
3185         .init_display_count = NULL,
3186         .set_allowed_mask = smu_v11_0_set_allowed_mask,
3187         .get_enabled_mask = smu_cmn_get_enabled_mask,
3188         .feature_is_enabled = smu_cmn_feature_is_enabled,
3189         .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception,
3190         .notify_display_change = NULL,
3191         .set_power_limit = smu_v11_0_set_power_limit,
3192         .init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
3193         .enable_thermal_alert = smu_v11_0_enable_thermal_alert,
3194         .disable_thermal_alert = smu_v11_0_disable_thermal_alert,
3195         .set_min_dcef_deep_sleep = NULL,
3196         .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
3197         .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
3198         .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
3199         .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
3200         .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
3201         .gfx_off_control = smu_v11_0_gfx_off_control,
3202         .register_irq_handler = smu_v11_0_register_irq_handler,
3203         .set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
3204         .get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
3205         .baco_is_support= sienna_cichlid_is_baco_supported,
3206         .baco_get_state = smu_v11_0_baco_get_state,
3207         .baco_set_state = smu_v11_0_baco_set_state,
3208         .baco_enter = smu_v11_0_baco_enter,
3209         .baco_exit = smu_v11_0_baco_exit,
3210         .mode1_reset_is_support = sienna_cichlid_is_mode1_reset_supported,
3211         .mode1_reset = smu_v11_0_mode1_reset,
3212         .get_dpm_ultimate_freq = sienna_cichlid_get_dpm_ultimate_freq,
3213         .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
3214         .set_default_od_settings = sienna_cichlid_set_default_od_settings,
3215         .od_edit_dpm_table = sienna_cichlid_od_edit_dpm_table,
3216         .run_btc = sienna_cichlid_run_btc,
3217         .set_power_source = smu_v11_0_set_power_source,
3218         .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
3219         .set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
3220         .get_gpu_metrics = sienna_cichlid_get_gpu_metrics,
3221         .enable_mgpu_fan_boost = sienna_cichlid_enable_mgpu_fan_boost,
3222         .gfx_ulv_control = smu_v11_0_gfx_ulv_control,
3223         .deep_sleep_control = smu_v11_0_deep_sleep_control,
3224         .get_fan_parameters = sienna_cichlid_get_fan_parameters,
3225         .interrupt_work = smu_v11_0_interrupt_work,
3226         .gpo_control = sienna_cichlid_gpo_control,
3227         .set_mp1_state = sienna_cichlid_set_mp1_state,
3228 };
3229
3230 void sienna_cichlid_set_ppt_funcs(struct smu_context *smu)
3231 {
3232         smu->ppt_funcs = &sienna_cichlid_ppt_funcs;
3233         smu->message_map = sienna_cichlid_message_map;
3234         smu->clock_map = sienna_cichlid_clk_map;
3235         smu->feature_map = sienna_cichlid_feature_mask_map;
3236         smu->table_map = sienna_cichlid_table_map;
3237         smu->pwr_src_map = sienna_cichlid_pwr_src_map;
3238         smu->workload_map = sienna_cichlid_workload_map;
3239 }