Merge tag 'for-6.8-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / pm / swsmu / smu14 / smu_v14_0_0_ppt.c
1 /*
2  * Copyright 2023 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 #include "smu_types.h"
25 #define SWSMU_CODE_LAYER_L2
26
27 #include "amdgpu.h"
28 #include "amdgpu_smu.h"
29 #include "smu_v14_0.h"
30 #include "smu14_driver_if_v14_0_0.h"
31 #include "smu_v14_0_0_ppt.h"
32 #include "smu_v14_0_0_ppsmc.h"
33 #include "smu_v14_0_0_pmfw.h"
34 #include "smu_cmn.h"
35
36 /*
37  * DO NOT use these for err/warn/info/debug messages.
38  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
39  * They are more MGPU friendly.
40  */
41 #undef pr_err
42 #undef pr_warn
43 #undef pr_info
44 #undef pr_debug
45
46 #define mmMP1_SMN_C2PMSG_66                     0x0282
47 #define mmMP1_SMN_C2PMSG_66_BASE_IDX            0
48
49 #define mmMP1_SMN_C2PMSG_82                     0x0292
50 #define mmMP1_SMN_C2PMSG_82_BASE_IDX            0
51
52 #define mmMP1_SMN_C2PMSG_90                     0x029a
53 #define mmMP1_SMN_C2PMSG_90_BASE_IDX                0
54
55 #define FEATURE_MASK(feature) (1ULL << feature)
56 #define SMC_DPM_FEATURE ( \
57         FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \
58         FEATURE_MASK(FEATURE_VCN_DPM_BIT)        | \
59         FEATURE_MASK(FEATURE_FCLK_DPM_BIT)       | \
60         FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT)     | \
61         FEATURE_MASK(FEATURE_LCLK_DPM_BIT)       | \
62         FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT)    | \
63         FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \
64         FEATURE_MASK(FEATURE_ISP_DPM_BIT)| \
65         FEATURE_MASK(FEATURE_IPU_DPM_BIT)       | \
66         FEATURE_MASK(FEATURE_GFX_DPM_BIT)       | \
67         FEATURE_MASK(FEATURE_VPE_DPM_BIT))
68
69 static struct cmn2asic_msg_mapping smu_v14_0_0_message_map[SMU_MSG_MAX_COUNT] = {
70         MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage,                          1),
71         MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetPmfwVersion,                       1),
72         MSG_MAP(GetDriverIfVersion,             PPSMC_MSG_GetDriverIfVersion,           1),
73         MSG_MAP(PowerDownVcn,                   PPSMC_MSG_PowerDownVcn,                         1),
74         MSG_MAP(PowerUpVcn,                     PPSMC_MSG_PowerUpVcn,                           1),
75         MSG_MAP(SetHardMinVcn,                  PPSMC_MSG_SetHardMinVcn,                        1),
76         MSG_MAP(SetSoftMinGfxclk,               PPSMC_MSG_SetSoftMinGfxclk,                     1),
77         MSG_MAP(PrepareMp1ForUnload,            PPSMC_MSG_PrepareMp1ForUnload,          1),
78         MSG_MAP(SetDriverDramAddrHigh,          PPSMC_MSG_SetDriverDramAddrHigh,        1),
79         MSG_MAP(SetDriverDramAddrLow,           PPSMC_MSG_SetDriverDramAddrLow,         1),
80         MSG_MAP(TransferTableSmu2Dram,          PPSMC_MSG_TransferTableSmu2Dram,        1),
81         MSG_MAP(TransferTableDram2Smu,          PPSMC_MSG_TransferTableDram2Smu,        1),
82         MSG_MAP(GfxDeviceDriverReset,           PPSMC_MSG_GfxDeviceDriverReset,         1),
83         MSG_MAP(GetEnabledSmuFeatures,          PPSMC_MSG_GetEnabledSmuFeatures,        1),
84         MSG_MAP(SetHardMinSocclkByFreq,         PPSMC_MSG_SetHardMinSocclkByFreq,       1),
85         MSG_MAP(SetSoftMinFclk,                 PPSMC_MSG_SetSoftMinFclk,                       1),
86         MSG_MAP(SetSoftMinVcn,                  PPSMC_MSG_SetSoftMinVcn,                        1),
87         MSG_MAP(EnableGfxImu,                   PPSMC_MSG_EnableGfxImu,                         1),
88         MSG_MAP(AllowGfxOff,                    PPSMC_MSG_AllowGfxOff,                          1),
89         MSG_MAP(DisallowGfxOff,                 PPSMC_MSG_DisallowGfxOff,                       1),
90         MSG_MAP(SetSoftMaxGfxClk,               PPSMC_MSG_SetSoftMaxGfxClk,                     1),
91         MSG_MAP(SetHardMinGfxClk,               PPSMC_MSG_SetHardMinGfxClk,                     1),
92         MSG_MAP(SetSoftMaxSocclkByFreq,         PPSMC_MSG_SetSoftMaxSocclkByFreq,       1),
93         MSG_MAP(SetSoftMaxFclkByFreq,           PPSMC_MSG_SetSoftMaxFclkByFreq,         1),
94         MSG_MAP(SetSoftMaxVcn,                  PPSMC_MSG_SetSoftMaxVcn,                        1),
95         MSG_MAP(PowerDownJpeg,                  PPSMC_MSG_PowerDownJpeg,                        1),
96         MSG_MAP(PowerUpJpeg,                    PPSMC_MSG_PowerUpJpeg,                          1),
97         MSG_MAP(SetHardMinFclkByFreq,           PPSMC_MSG_SetHardMinFclkByFreq,         1),
98         MSG_MAP(SetSoftMinSocclkByFreq,         PPSMC_MSG_SetSoftMinSocclkByFreq,       1),
99         MSG_MAP(PowerDownIspByTile,             PPSMC_MSG_PowerDownIspByTile,           1),
100         MSG_MAP(PowerUpIspByTile,               PPSMC_MSG_PowerUpIspByTile,                     1),
101         MSG_MAP(SetHardMinIspiclkByFreq,        PPSMC_MSG_SetHardMinIspiclkByFreq,      1),
102         MSG_MAP(SetHardMinIspxclkByFreq,        PPSMC_MSG_SetHardMinIspxclkByFreq,      1),
103         MSG_MAP(PowerUpVpe,                     PPSMC_MSG_PowerUpVpe,                           1),
104         MSG_MAP(PowerDownVpe,                   PPSMC_MSG_PowerDownVpe,                         1),
105         MSG_MAP(PowerUpUmsch,                   PPSMC_MSG_PowerUpUmsch,                         1),
106         MSG_MAP(PowerDownUmsch,                 PPSMC_MSG_PowerDownUmsch,                       1),
107         MSG_MAP(SetSoftMaxVpe,                  PPSMC_MSG_SetSoftMaxVpe,                        1),
108         MSG_MAP(SetSoftMinVpe,                  PPSMC_MSG_SetSoftMinVpe,                        1),
109 };
110
111 static struct cmn2asic_mapping smu_v14_0_0_feature_mask_map[SMU_FEATURE_COUNT] = {
112         FEA_MAP(CCLK_DPM),
113         FEA_MAP(FAN_CONTROLLER),
114         FEA_MAP(PPT),
115         FEA_MAP(TDC),
116         FEA_MAP(THERMAL),
117         FEA_MAP(VCN_DPM),
118         FEA_MAP_REVERSE(FCLK),
119         FEA_MAP_REVERSE(SOCCLK),
120         FEA_MAP(LCLK_DPM),
121         FEA_MAP(SHUBCLK_DPM),
122         FEA_MAP(DCFCLK_DPM),
123         FEA_MAP_HALF_REVERSE(GFX),
124         FEA_MAP(DS_GFXCLK),
125         FEA_MAP(DS_SOCCLK),
126         FEA_MAP(DS_LCLK),
127         FEA_MAP(LOW_POWER_DCNCLKS),
128         FEA_MAP(DS_FCLK),
129         FEA_MAP(DS_MP1CLK),
130         FEA_MAP(PSI),
131         FEA_MAP(PROCHOT),
132         FEA_MAP(CPUOFF),
133         FEA_MAP(STAPM),
134         FEA_MAP(S0I3),
135         FEA_MAP(PERF_LIMIT),
136         FEA_MAP(CORE_DLDO),
137         FEA_MAP(DS_VCN),
138         FEA_MAP(CPPC),
139         FEA_MAP(DF_CSTATES),
140         FEA_MAP(ATHUB_PG),
141 };
142
143 static struct cmn2asic_mapping smu_v14_0_0_table_map[SMU_TABLE_COUNT] = {
144         TAB_MAP_VALID(WATERMARKS),
145         TAB_MAP_VALID(SMU_METRICS),
146         TAB_MAP_VALID(CUSTOM_DPM),
147         TAB_MAP_VALID(DPMCLOCKS),
148 };
149
150 static int smu_v14_0_0_init_smc_tables(struct smu_context *smu)
151 {
152         struct smu_table_context *smu_table = &smu->smu_table;
153         struct smu_table *tables = smu_table->tables;
154
155         SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
156                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
157         SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),
158                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
159         SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
160                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
161
162         smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
163         if (!smu_table->metrics_table)
164                 goto err0_out;
165         smu_table->metrics_time = 0;
166
167         smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL);
168         if (!smu_table->clocks_table)
169                 goto err1_out;
170
171         smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
172         if (!smu_table->watermarks_table)
173                 goto err2_out;
174
175         smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v3_0);
176         smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
177         if (!smu_table->gpu_metrics_table)
178                 goto err3_out;
179
180         return 0;
181
182 err3_out:
183         kfree(smu_table->watermarks_table);
184 err2_out:
185         kfree(smu_table->clocks_table);
186 err1_out:
187         kfree(smu_table->metrics_table);
188 err0_out:
189         return -ENOMEM;
190 }
191
192 static int smu_v14_0_0_fini_smc_tables(struct smu_context *smu)
193 {
194         struct smu_table_context *smu_table = &smu->smu_table;
195
196         kfree(smu_table->clocks_table);
197         smu_table->clocks_table = NULL;
198
199         kfree(smu_table->metrics_table);
200         smu_table->metrics_table = NULL;
201
202         kfree(smu_table->watermarks_table);
203         smu_table->watermarks_table = NULL;
204
205         kfree(smu_table->gpu_metrics_table);
206         smu_table->gpu_metrics_table = NULL;
207
208         return 0;
209 }
210
211 static int smu_v14_0_0_system_features_control(struct smu_context *smu, bool en)
212 {
213         struct amdgpu_device *adev = smu->adev;
214         int ret = 0;
215
216         if (!en && !adev->in_s0ix)
217                 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
218
219         return ret;
220 }
221
222 static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
223                                             MetricsMember_t member,
224                                             uint32_t *value)
225 {
226         struct smu_table_context *smu_table = &smu->smu_table;
227
228         SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
229         int ret = 0;
230
231         ret = smu_cmn_get_metrics_table(smu, NULL, false);
232         if (ret)
233                 return ret;
234
235         switch (member) {
236         case METRICS_AVERAGE_GFXCLK:
237                 *value = metrics->GfxclkFrequency;
238                 break;
239         case METRICS_AVERAGE_SOCCLK:
240                 *value = metrics->SocclkFrequency;
241                 break;
242         case METRICS_AVERAGE_VCLK:
243                 *value = metrics->VclkFrequency;
244                 break;
245         case METRICS_AVERAGE_DCLK:
246                 *value = 0;
247                 break;
248         case METRICS_AVERAGE_UCLK:
249                 *value = metrics->MemclkFrequency;
250                 break;
251         case METRICS_AVERAGE_FCLK:
252                 *value = metrics->FclkFrequency;
253                 break;
254         case METRICS_AVERAGE_VPECLK:
255                 *value = metrics->VpeclkFrequency;
256                 break;
257         case METRICS_AVERAGE_IPUCLK:
258                 *value = metrics->IpuclkFrequency;
259                 break;
260         case METRICS_AVERAGE_MPIPUCLK:
261                 *value = metrics->MpipuclkFrequency;
262                 break;
263         case METRICS_AVERAGE_GFXACTIVITY:
264                 *value = metrics->GfxActivity / 100;
265                 break;
266         case METRICS_AVERAGE_VCNACTIVITY:
267                 *value = metrics->VcnActivity / 100;
268                 break;
269         case METRICS_AVERAGE_SOCKETPOWER:
270         case METRICS_CURR_SOCKETPOWER:
271                 *value = (metrics->SocketPower / 1000 << 8) +
272                 (metrics->SocketPower % 1000 / 10);
273                 break;
274         case METRICS_TEMPERATURE_EDGE:
275                 *value = metrics->GfxTemperature / 100 *
276                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
277                 break;
278         case METRICS_TEMPERATURE_HOTSPOT:
279                 *value = metrics->SocTemperature / 100 *
280                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
281                 break;
282         case METRICS_THROTTLER_RESIDENCY_PROCHOT:
283                 *value = metrics->ThrottleResidency_PROCHOT;
284                 break;
285         case METRICS_THROTTLER_RESIDENCY_SPL:
286                 *value = metrics->ThrottleResidency_SPL;
287                 break;
288         case METRICS_THROTTLER_RESIDENCY_FPPT:
289                 *value = metrics->ThrottleResidency_FPPT;
290                 break;
291         case METRICS_THROTTLER_RESIDENCY_SPPT:
292                 *value = metrics->ThrottleResidency_SPPT;
293                 break;
294         case METRICS_THROTTLER_RESIDENCY_THM_CORE:
295                 *value = metrics->ThrottleResidency_THM_CORE;
296                 break;
297         case METRICS_THROTTLER_RESIDENCY_THM_GFX:
298                 *value = metrics->ThrottleResidency_THM_GFX;
299                 break;
300         case METRICS_THROTTLER_RESIDENCY_THM_SOC:
301                 *value = metrics->ThrottleResidency_THM_SOC;
302                 break;
303         case METRICS_VOLTAGE_VDDGFX:
304                 *value = 0;
305                 break;
306         case METRICS_VOLTAGE_VDDSOC:
307                 *value = 0;
308                 break;
309         case METRICS_SS_APU_SHARE:
310                 /* return the percentage of APU power with respect to APU's power limit.
311                  * percentage is reported, this isn't boost value. Smartshift power
312                  * boost/shift is only when the percentage is more than 100.
313                  */
314                 if (metrics->StapmOpnLimit > 0)
315                         *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit;
316                 else
317                         *value = 0;
318                 break;
319         case METRICS_SS_DGPU_SHARE:
320                 /* return the percentage of dGPU power with respect to dGPU's power limit.
321                  * percentage is reported, this isn't boost value. Smartshift power
322                  * boost/shift is only when the percentage is more than 100.
323                  */
324                 if ((metrics->dGpuPower > 0) &&
325                     (metrics->StapmCurrentLimit > metrics->StapmOpnLimit))
326                         *value = (metrics->dGpuPower * 100) /
327                                  (metrics->StapmCurrentLimit - metrics->StapmOpnLimit);
328                 else
329                         *value = 0;
330                 break;
331         default:
332                 *value = UINT_MAX;
333                 break;
334         }
335
336         return ret;
337 }
338
339 static int smu_v14_0_0_read_sensor(struct smu_context *smu,
340                                    enum amd_pp_sensors sensor,
341                                    void *data, uint32_t *size)
342 {
343         int ret = 0;
344
345         if (!data || !size)
346                 return -EINVAL;
347
348         switch (sensor) {
349         case AMDGPU_PP_SENSOR_GPU_LOAD:
350                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
351                                                        METRICS_AVERAGE_GFXACTIVITY,
352                                                        (uint32_t *)data);
353                 *size = 4;
354                 break;
355         case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
356                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
357                                                        METRICS_AVERAGE_SOCKETPOWER,
358                                                        (uint32_t *)data);
359                 *size = 4;
360                 break;
361         case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
362                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
363                                                        METRICS_CURR_SOCKETPOWER,
364                                                        (uint32_t *)data);
365                 *size = 4;
366                 break;
367         case AMDGPU_PP_SENSOR_EDGE_TEMP:
368                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
369                                                        METRICS_TEMPERATURE_EDGE,
370                                                        (uint32_t *)data);
371                 *size = 4;
372                 break;
373         case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
374                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
375                                                        METRICS_TEMPERATURE_HOTSPOT,
376                                                        (uint32_t *)data);
377                 *size = 4;
378                 break;
379         case AMDGPU_PP_SENSOR_GFX_MCLK:
380                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
381                                                        METRICS_AVERAGE_UCLK,
382                                                        (uint32_t *)data);
383                 *(uint32_t *)data *= 100;
384                 *size = 4;
385                 break;
386         case AMDGPU_PP_SENSOR_GFX_SCLK:
387                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
388                                                        METRICS_AVERAGE_GFXCLK,
389                                                        (uint32_t *)data);
390                 *(uint32_t *)data *= 100;
391                 *size = 4;
392                 break;
393         case AMDGPU_PP_SENSOR_VDDGFX:
394                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
395                                                        METRICS_VOLTAGE_VDDGFX,
396                                                        (uint32_t *)data);
397                 *size = 4;
398                 break;
399         case AMDGPU_PP_SENSOR_VDDNB:
400                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
401                                                        METRICS_VOLTAGE_VDDSOC,
402                                                        (uint32_t *)data);
403                 *size = 4;
404                 break;
405         case AMDGPU_PP_SENSOR_SS_APU_SHARE:
406                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
407                                                        METRICS_SS_APU_SHARE,
408                                                        (uint32_t *)data);
409                 *size = 4;
410                 break;
411         case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
412                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
413                                                        METRICS_SS_DGPU_SHARE,
414                                                        (uint32_t *)data);
415                 *size = 4;
416                 break;
417         default:
418                 ret = -EOPNOTSUPP;
419                 break;
420         }
421
422         return ret;
423 }
424
425 static bool smu_v14_0_0_is_dpm_running(struct smu_context *smu)
426 {
427         int ret = 0;
428         uint64_t feature_enabled;
429
430         ret = smu_cmn_get_enabled_mask(smu, &feature_enabled);
431
432         if (ret)
433                 return false;
434
435         return !!(feature_enabled & SMC_DPM_FEATURE);
436 }
437
438 static int smu_v14_0_0_set_watermarks_table(struct smu_context *smu,
439                                             struct pp_smu_wm_range_sets *clock_ranges)
440 {
441         int i;
442         int ret = 0;
443         Watermarks_t *table = smu->smu_table.watermarks_table;
444
445         if (!table || !clock_ranges)
446                 return -EINVAL;
447
448         if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES ||
449                 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES)
450                 return -EINVAL;
451
452         for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
453                 table->WatermarkRow[WM_DCFCLK][i].MinClock =
454                         clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
455                 table->WatermarkRow[WM_DCFCLK][i].MaxClock =
456                         clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
457                 table->WatermarkRow[WM_DCFCLK][i].MinMclk =
458                         clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
459                 table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
460                         clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
461
462                 table->WatermarkRow[WM_DCFCLK][i].WmSetting =
463                         clock_ranges->reader_wm_sets[i].wm_inst;
464         }
465
466         for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
467                 table->WatermarkRow[WM_SOCCLK][i].MinClock =
468                         clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
469                 table->WatermarkRow[WM_SOCCLK][i].MaxClock =
470                         clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
471                 table->WatermarkRow[WM_SOCCLK][i].MinMclk =
472                         clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
473                 table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
474                         clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
475
476                 table->WatermarkRow[WM_SOCCLK][i].WmSetting =
477                         clock_ranges->writer_wm_sets[i].wm_inst;
478         }
479
480         smu->watermarks_bitmap |= WATERMARKS_EXIST;
481
482         /* pass data to smu controller */
483         if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
484              !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
485                 ret = smu_cmn_write_watermarks_table(smu);
486                 if (ret) {
487                         dev_err(smu->adev->dev, "Failed to update WMTABLE!");
488                         return ret;
489                 }
490                 smu->watermarks_bitmap |= WATERMARKS_LOADED;
491         }
492
493         return 0;
494 }
495
496 static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
497                                                 void **table)
498 {
499         struct smu_table_context *smu_table = &smu->smu_table;
500         struct gpu_metrics_v3_0 *gpu_metrics =
501                 (struct gpu_metrics_v3_0 *)smu_table->gpu_metrics_table;
502         SmuMetrics_t metrics;
503         int ret = 0;
504
505         ret = smu_cmn_get_metrics_table(smu, &metrics, true);
506         if (ret)
507                 return ret;
508
509         smu_cmn_init_soft_gpu_metrics(gpu_metrics, 3, 0);
510
511         gpu_metrics->temperature_gfx = metrics.GfxTemperature;
512         gpu_metrics->temperature_soc = metrics.SocTemperature;
513         memcpy(&gpu_metrics->temperature_core[0],
514                 &metrics.CoreTemperature[0],
515                 sizeof(uint16_t) * 16);
516         gpu_metrics->temperature_skin = metrics.SkinTemp;
517
518         gpu_metrics->average_gfx_activity = metrics.GfxActivity;
519         gpu_metrics->average_vcn_activity = metrics.VcnActivity;
520         memcpy(&gpu_metrics->average_ipu_activity[0],
521                 &metrics.IpuBusy[0],
522                 sizeof(uint16_t) * 8);
523         memcpy(&gpu_metrics->average_core_c0_activity[0],
524                 &metrics.CoreC0Residency[0],
525                 sizeof(uint16_t) * 16);
526         gpu_metrics->average_dram_reads = metrics.DRAMReads;
527         gpu_metrics->average_dram_writes = metrics.DRAMWrites;
528         gpu_metrics->average_ipu_reads = metrics.IpuReads;
529         gpu_metrics->average_ipu_writes = metrics.IpuWrites;
530
531         gpu_metrics->average_socket_power = metrics.SocketPower;
532         gpu_metrics->average_ipu_power = metrics.IpuPower;
533         gpu_metrics->average_apu_power = metrics.ApuPower;
534         gpu_metrics->average_gfx_power = metrics.GfxPower;
535         gpu_metrics->average_dgpu_power = metrics.dGpuPower;
536         gpu_metrics->average_all_core_power = metrics.AllCorePower;
537         gpu_metrics->average_sys_power = metrics.Psys;
538         memcpy(&gpu_metrics->average_core_power[0],
539                 &metrics.CorePower[0],
540                 sizeof(uint16_t) * 16);
541
542         gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency;
543         gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency;
544         gpu_metrics->average_vpeclk_frequency = metrics.VpeclkFrequency;
545         gpu_metrics->average_fclk_frequency = metrics.FclkFrequency;
546         gpu_metrics->average_vclk_frequency = metrics.VclkFrequency;
547         gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency;
548         gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency;
549         gpu_metrics->average_mpipu_frequency = metrics.MpipuclkFrequency;
550
551         memcpy(&gpu_metrics->current_coreclk[0],
552                 &metrics.CoreFrequency[0],
553                 sizeof(uint16_t) * 16);
554         gpu_metrics->current_core_maxfreq = metrics.InfrastructureCpuMaxFreq;
555         gpu_metrics->current_gfx_maxfreq = metrics.InfrastructureGfxMaxFreq;
556
557         gpu_metrics->throttle_residency_prochot = metrics.ThrottleResidency_PROCHOT;
558         gpu_metrics->throttle_residency_spl = metrics.ThrottleResidency_SPL;
559         gpu_metrics->throttle_residency_fppt = metrics.ThrottleResidency_FPPT;
560         gpu_metrics->throttle_residency_sppt = metrics.ThrottleResidency_SPPT;
561         gpu_metrics->throttle_residency_thm_core = metrics.ThrottleResidency_THM_CORE;
562         gpu_metrics->throttle_residency_thm_gfx = metrics.ThrottleResidency_THM_GFX;
563         gpu_metrics->throttle_residency_thm_soc = metrics.ThrottleResidency_THM_SOC;
564
565         gpu_metrics->time_filter_alphavalue = metrics.FilterAlphaValue;
566         gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
567
568         *table = (void *)gpu_metrics;
569
570         return sizeof(struct gpu_metrics_v3_0);
571 }
572
573 static int smu_v14_0_0_mode2_reset(struct smu_context *smu)
574 {
575         int ret;
576
577         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset,
578                                                SMU_RESET_MODE_2, NULL);
579
580         if (ret)
581                 dev_err(smu->adev->dev, "Failed to mode2 reset!\n");
582
583         return ret;
584 }
585
586 static int smu_v14_0_0_get_dpm_freq_by_index(struct smu_context *smu,
587                                                 enum smu_clk_type clk_type,
588                                                 uint32_t dpm_level,
589                                                 uint32_t *freq)
590 {
591         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
592
593         if (!clk_table || clk_type >= SMU_CLK_COUNT)
594                 return -EINVAL;
595
596         switch (clk_type) {
597         case SMU_SOCCLK:
598                 if (dpm_level >= clk_table->NumSocClkLevelsEnabled)
599                         return -EINVAL;
600                 *freq = clk_table->SocClocks[dpm_level];
601                 break;
602         case SMU_VCLK:
603                 if (dpm_level >= clk_table->VcnClkLevelsEnabled)
604                         return -EINVAL;
605                 *freq = clk_table->VClocks[dpm_level];
606                 break;
607         case SMU_DCLK:
608                 if (dpm_level >= clk_table->VcnClkLevelsEnabled)
609                         return -EINVAL;
610                 *freq = clk_table->DClocks[dpm_level];
611                 break;
612         case SMU_UCLK:
613         case SMU_MCLK:
614                 if (dpm_level >= clk_table->NumMemPstatesEnabled)
615                         return -EINVAL;
616                 *freq = clk_table->MemPstateTable[dpm_level].MemClk;
617                 break;
618         case SMU_FCLK:
619                 if (dpm_level >= clk_table->NumFclkLevelsEnabled)
620                         return -EINVAL;
621                 *freq = clk_table->FclkClocks_Freq[dpm_level];
622                 break;
623         default:
624                 return -EINVAL;
625         }
626
627         return 0;
628 }
629
630 static bool smu_v14_0_0_clk_dpm_is_enabled(struct smu_context *smu,
631                                                 enum smu_clk_type clk_type)
632 {
633         enum smu_feature_mask feature_id = 0;
634
635         switch (clk_type) {
636         case SMU_MCLK:
637         case SMU_UCLK:
638         case SMU_FCLK:
639                 feature_id = SMU_FEATURE_DPM_FCLK_BIT;
640                 break;
641         case SMU_GFXCLK:
642         case SMU_SCLK:
643                 feature_id = SMU_FEATURE_DPM_GFXCLK_BIT;
644                 break;
645         case SMU_SOCCLK:
646                 feature_id = SMU_FEATURE_DPM_SOCCLK_BIT;
647                 break;
648         case SMU_VCLK:
649         case SMU_DCLK:
650                 feature_id = SMU_FEATURE_VCN_DPM_BIT;
651                 break;
652         default:
653                 return true;
654         }
655
656         return smu_cmn_feature_is_enabled(smu, feature_id);
657 }
658
659 static int smu_v14_0_0_get_dpm_ultimate_freq(struct smu_context *smu,
660                                                         enum smu_clk_type clk_type,
661                                                         uint32_t *min,
662                                                         uint32_t *max)
663 {
664         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
665         uint32_t clock_limit;
666         uint32_t max_dpm_level, min_dpm_level;
667         int ret = 0;
668
669         if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) {
670                 switch (clk_type) {
671                 case SMU_MCLK:
672                 case SMU_UCLK:
673                         clock_limit = smu->smu_table.boot_values.uclk;
674                         break;
675                 case SMU_FCLK:
676                         clock_limit = smu->smu_table.boot_values.fclk;
677                         break;
678                 case SMU_GFXCLK:
679                 case SMU_SCLK:
680                         clock_limit = smu->smu_table.boot_values.gfxclk;
681                         break;
682                 case SMU_SOCCLK:
683                         clock_limit = smu->smu_table.boot_values.socclk;
684                         break;
685                 case SMU_VCLK:
686                         clock_limit = smu->smu_table.boot_values.vclk;
687                         break;
688                 case SMU_DCLK:
689                         clock_limit = smu->smu_table.boot_values.dclk;
690                         break;
691                 default:
692                         clock_limit = 0;
693                         break;
694                 }
695
696                 /* clock in Mhz unit */
697                 if (min)
698                         *min = clock_limit / 100;
699                 if (max)
700                         *max = clock_limit / 100;
701
702                 return 0;
703         }
704
705         if (max) {
706                 switch (clk_type) {
707                 case SMU_GFXCLK:
708                 case SMU_SCLK:
709                         *max = clk_table->MaxGfxClk;
710                         break;
711                 case SMU_MCLK:
712                 case SMU_UCLK:
713                 case SMU_FCLK:
714                         max_dpm_level = 0;
715                         break;
716                 case SMU_SOCCLK:
717                         max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1;
718                         break;
719                 case SMU_VCLK:
720                 case SMU_DCLK:
721                         max_dpm_level = clk_table->VcnClkLevelsEnabled - 1;
722                         break;
723                 default:
724                         ret = -EINVAL;
725                         goto failed;
726                 }
727
728                 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
729                         ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, max_dpm_level, max);
730                         if (ret)
731                                 goto failed;
732                 }
733         }
734
735         if (min) {
736                 switch (clk_type) {
737                 case SMU_GFXCLK:
738                 case SMU_SCLK:
739                         *min = clk_table->MinGfxClk;
740                         break;
741                 case SMU_MCLK:
742                 case SMU_UCLK:
743                         min_dpm_level = clk_table->NumMemPstatesEnabled - 1;
744                         break;
745                 case SMU_FCLK:
746                         min_dpm_level = clk_table->NumFclkLevelsEnabled - 1;
747                         break;
748                 case SMU_SOCCLK:
749                         min_dpm_level = 0;
750                         break;
751                 case SMU_VCLK:
752                 case SMU_DCLK:
753                         min_dpm_level = 0;
754                         break;
755                 default:
756                         ret = -EINVAL;
757                         goto failed;
758                 }
759
760                 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
761                         ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, min_dpm_level, min);
762                         if (ret)
763                                 goto failed;
764                 }
765         }
766
767 failed:
768         return ret;
769 }
770
771 static int smu_v14_0_0_get_current_clk_freq(struct smu_context *smu,
772                                             enum smu_clk_type clk_type,
773                                             uint32_t *value)
774 {
775         MetricsMember_t member_type;
776
777         switch (clk_type) {
778         case SMU_SOCCLK:
779                 member_type = METRICS_AVERAGE_SOCCLK;
780                 break;
781         case SMU_VCLK:
782                 member_type = METRICS_AVERAGE_VCLK;
783                 break;
784         case SMU_DCLK:
785                 member_type = METRICS_AVERAGE_DCLK;
786                 break;
787         case SMU_MCLK:
788                 member_type = METRICS_AVERAGE_UCLK;
789                 break;
790         case SMU_FCLK:
791                 member_type = METRICS_AVERAGE_FCLK;
792                 break;
793         case SMU_GFXCLK:
794         case SMU_SCLK:
795                 member_type = METRICS_AVERAGE_GFXCLK;
796                 break;
797         default:
798                 return -EINVAL;
799         }
800
801         return smu_v14_0_0_get_smu_metrics_data(smu, member_type, value);
802 }
803
804 static int smu_v14_0_0_get_dpm_level_count(struct smu_context *smu,
805                                            enum smu_clk_type clk_type,
806                                            uint32_t *count)
807 {
808         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
809
810         switch (clk_type) {
811         case SMU_SOCCLK:
812                 *count = clk_table->NumSocClkLevelsEnabled;
813                 break;
814         case SMU_VCLK:
815                 *count = clk_table->VcnClkLevelsEnabled;
816                 break;
817         case SMU_DCLK:
818                 *count = clk_table->VcnClkLevelsEnabled;
819                 break;
820         case SMU_MCLK:
821                 *count = clk_table->NumMemPstatesEnabled;
822                 break;
823         case SMU_FCLK:
824                 *count = clk_table->NumFclkLevelsEnabled;
825                 break;
826         default:
827                 break;
828         }
829
830         return 0;
831 }
832
833 static int smu_v14_0_0_print_clk_levels(struct smu_context *smu,
834                                         enum smu_clk_type clk_type, char *buf)
835 {
836         int i, size = 0, ret = 0;
837         uint32_t cur_value = 0, value = 0, count = 0;
838         uint32_t min, max;
839
840         smu_cmn_get_sysfs_buf(&buf, &size);
841
842         switch (clk_type) {
843         case SMU_OD_SCLK:
844                 size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
845                 size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
846                 (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq);
847                 size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
848                 (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq);
849                 break;
850         case SMU_OD_RANGE:
851                 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
852                 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
853                                       smu->gfx_default_hard_min_freq,
854                                       smu->gfx_default_soft_max_freq);
855                 break;
856         case SMU_SOCCLK:
857         case SMU_VCLK:
858         case SMU_DCLK:
859         case SMU_MCLK:
860         case SMU_FCLK:
861                 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value);
862                 if (ret)
863                         break;
864
865                 ret = smu_v14_0_0_get_dpm_level_count(smu, clk_type, &count);
866                 if (ret)
867                         break;
868
869                 for (i = 0; i < count; i++) {
870                         ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
871                         if (ret)
872                                 break;
873
874                         size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value,
875                                               cur_value == value ? "*" : "");
876                 }
877                 break;
878         case SMU_GFXCLK:
879         case SMU_SCLK:
880                 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value);
881                 if (ret)
882                         break;
883                 min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
884                 max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
885                 if (cur_value  == max)
886                         i = 2;
887                 else if (cur_value == min)
888                         i = 0;
889                 else
890                         i = 1;
891                 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
892                                       i == 0 ? "*" : "");
893                 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
894                                       i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */
895                                       i == 1 ? "*" : "");
896                 size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
897                                       i == 2 ? "*" : "");
898                 break;
899         default:
900                 break;
901         }
902
903         return size;
904 }
905
906 static int smu_v14_0_0_set_soft_freq_limited_range(struct smu_context *smu,
907                                                    enum smu_clk_type clk_type,
908                                                    uint32_t min,
909                                                    uint32_t max)
910 {
911         enum smu_message_type msg_set_min, msg_set_max;
912         int ret = 0;
913
914         if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type))
915                 return -EINVAL;
916
917         switch (clk_type) {
918         case SMU_GFXCLK:
919         case SMU_SCLK:
920                 msg_set_min = SMU_MSG_SetHardMinGfxClk;
921                 msg_set_max = SMU_MSG_SetSoftMaxGfxClk;
922                 break;
923         case SMU_FCLK:
924                 msg_set_min = SMU_MSG_SetHardMinFclkByFreq;
925                 msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq;
926                 break;
927         case SMU_SOCCLK:
928                 msg_set_min = SMU_MSG_SetHardMinSocclkByFreq;
929                 msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq;
930                 break;
931         case SMU_VCLK:
932         case SMU_DCLK:
933                 msg_set_min = SMU_MSG_SetHardMinVcn;
934                 msg_set_max = SMU_MSG_SetSoftMaxVcn;
935                 break;
936         default:
937                 return -EINVAL;
938         }
939
940         ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_min, min, NULL);
941         if (ret)
942                 return ret;
943
944         return smu_cmn_send_smc_msg_with_param(smu, msg_set_max,
945                                                max, NULL);
946 }
947
948 static int smu_v14_0_0_force_clk_levels(struct smu_context *smu,
949                                         enum smu_clk_type clk_type,
950                                         uint32_t mask)
951 {
952         uint32_t soft_min_level = 0, soft_max_level = 0;
953         uint32_t min_freq = 0, max_freq = 0;
954         int ret = 0;
955
956         soft_min_level = mask ? (ffs(mask) - 1) : 0;
957         soft_max_level = mask ? (fls(mask) - 1) : 0;
958
959         switch (clk_type) {
960         case SMU_SOCCLK:
961         case SMU_FCLK:
962         case SMU_VCLK:
963         case SMU_DCLK:
964                 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq);
965                 if (ret)
966                         break;
967
968                 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq);
969                 if (ret)
970                         break;
971
972                 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
973                 break;
974         default:
975                 ret = -EINVAL;
976                 break;
977         }
978
979         return ret;
980 }
981
982 static int smu_v14_0_0_set_performance_level(struct smu_context *smu,
983                                              enum amd_dpm_forced_level level)
984 {
985         struct amdgpu_device *adev = smu->adev;
986         uint32_t sclk_min = 0, sclk_max = 0;
987         uint32_t fclk_min = 0, fclk_max = 0;
988         uint32_t socclk_min = 0, socclk_max = 0;
989         int ret = 0;
990
991         switch (level) {
992         case AMD_DPM_FORCED_LEVEL_HIGH:
993                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_max);
994                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_max);
995                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_max);
996                 sclk_min = sclk_max;
997                 fclk_min = fclk_max;
998                 socclk_min = socclk_max;
999                 break;
1000         case AMD_DPM_FORCED_LEVEL_LOW:
1001                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, NULL);
1002                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, NULL);
1003                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, NULL);
1004                 sclk_max = sclk_min;
1005                 fclk_max = fclk_min;
1006                 socclk_max = socclk_min;
1007                 break;
1008         case AMD_DPM_FORCED_LEVEL_AUTO:
1009                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, &sclk_max);
1010                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, &fclk_max);
1011                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, &socclk_max);
1012                 break;
1013         case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1014         case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1015         case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1016         case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1017                 /* Temporarily do nothing since the optimal clocks haven't been provided yet */
1018                 break;
1019         case AMD_DPM_FORCED_LEVEL_MANUAL:
1020         case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
1021                 return 0;
1022         default:
1023                 dev_err(adev->dev, "Invalid performance level %d\n", level);
1024                 return -EINVAL;
1025         }
1026
1027         if (sclk_min && sclk_max) {
1028                 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1029                                                               SMU_SCLK,
1030                                                               sclk_min,
1031                                                               sclk_max);
1032                 if (ret)
1033                         return ret;
1034
1035                 smu->gfx_actual_hard_min_freq = sclk_min;
1036                 smu->gfx_actual_soft_max_freq = sclk_max;
1037         }
1038
1039         if (fclk_min && fclk_max) {
1040                 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1041                                                               SMU_FCLK,
1042                                                               fclk_min,
1043                                                               fclk_max);
1044                 if (ret)
1045                         return ret;
1046         }
1047
1048         if (socclk_min && socclk_max) {
1049                 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1050                                                               SMU_SOCCLK,
1051                                                               socclk_min,
1052                                                               socclk_max);
1053                 if (ret)
1054                         return ret;
1055         }
1056
1057         return ret;
1058 }
1059
1060 static int smu_v14_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
1061 {
1062         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
1063
1064         smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
1065         smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
1066         smu->gfx_actual_hard_min_freq = 0;
1067         smu->gfx_actual_soft_max_freq = 0;
1068
1069         return 0;
1070 }
1071
1072 static int smu_v14_0_0_set_vpe_enable(struct smu_context *smu,
1073                                       bool enable)
1074 {
1075         return smu_cmn_send_smc_msg_with_param(smu, enable ?
1076                                                SMU_MSG_PowerUpVpe : SMU_MSG_PowerDownVpe,
1077                                                0, NULL);
1078 }
1079
1080 static int smu_v14_0_0_set_umsch_mm_enable(struct smu_context *smu,
1081                               bool enable)
1082 {
1083         return smu_cmn_send_smc_msg_with_param(smu, enable ?
1084                                                SMU_MSG_PowerUpUmsch : SMU_MSG_PowerDownUmsch,
1085                                                0, NULL);
1086 }
1087
1088 static int smu_14_0_0_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
1089 {
1090         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
1091         uint8_t idx;
1092
1093         /* Only the Clock information of SOC and VPE is copied to provide VPE DPM settings for use. */
1094         for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) {
1095                 clock_table->SocClocks[idx].Freq = (idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0;
1096                 clock_table->SocClocks[idx].Vol = 0;
1097         }
1098
1099         for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) {
1100                 clock_table->VPEClocks[idx].Freq = (idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0;
1101                 clock_table->VPEClocks[idx].Vol = 0;
1102         }
1103
1104         return 0;
1105 }
1106
1107 static const struct pptable_funcs smu_v14_0_0_ppt_funcs = {
1108         .check_fw_status = smu_v14_0_check_fw_status,
1109         .check_fw_version = smu_v14_0_check_fw_version,
1110         .init_smc_tables = smu_v14_0_0_init_smc_tables,
1111         .fini_smc_tables = smu_v14_0_0_fini_smc_tables,
1112         .get_vbios_bootup_values = smu_v14_0_get_vbios_bootup_values,
1113         .system_features_control = smu_v14_0_0_system_features_control,
1114         .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
1115         .send_smc_msg = smu_cmn_send_smc_msg,
1116         .dpm_set_vcn_enable = smu_v14_0_set_vcn_enable,
1117         .dpm_set_jpeg_enable = smu_v14_0_set_jpeg_enable,
1118         .set_default_dpm_table = smu_v14_0_set_default_dpm_tables,
1119         .read_sensor = smu_v14_0_0_read_sensor,
1120         .is_dpm_running = smu_v14_0_0_is_dpm_running,
1121         .set_watermarks_table = smu_v14_0_0_set_watermarks_table,
1122         .get_gpu_metrics = smu_v14_0_0_get_gpu_metrics,
1123         .get_enabled_mask = smu_cmn_get_enabled_mask,
1124         .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
1125         .set_driver_table_location = smu_v14_0_set_driver_table_location,
1126         .gfx_off_control = smu_v14_0_gfx_off_control,
1127         .mode2_reset = smu_v14_0_0_mode2_reset,
1128         .get_dpm_ultimate_freq = smu_v14_0_0_get_dpm_ultimate_freq,
1129         .od_edit_dpm_table = smu_v14_0_od_edit_dpm_table,
1130         .print_clk_levels = smu_v14_0_0_print_clk_levels,
1131         .force_clk_levels = smu_v14_0_0_force_clk_levels,
1132         .set_performance_level = smu_v14_0_0_set_performance_level,
1133         .set_fine_grain_gfx_freq_parameters = smu_v14_0_0_set_fine_grain_gfx_freq_parameters,
1134         .set_gfx_power_up_by_imu = smu_v14_0_set_gfx_power_up_by_imu,
1135         .dpm_set_vpe_enable = smu_v14_0_0_set_vpe_enable,
1136         .dpm_set_umsch_mm_enable = smu_v14_0_0_set_umsch_mm_enable,
1137         .get_dpm_clock_table = smu_14_0_0_get_dpm_table,
1138 };
1139
1140 static void smu_v14_0_0_set_smu_mailbox_registers(struct smu_context *smu)
1141 {
1142         struct amdgpu_device *adev = smu->adev;
1143
1144         smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82);
1145         smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66);
1146         smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
1147 }
1148
1149 void smu_v14_0_0_set_ppt_funcs(struct smu_context *smu)
1150 {
1151
1152         smu->ppt_funcs = &smu_v14_0_0_ppt_funcs;
1153         smu->message_map = smu_v14_0_0_message_map;
1154         smu->feature_map = smu_v14_0_0_feature_mask_map;
1155         smu->table_map = smu_v14_0_0_table_map;
1156         smu->is_apu = true;
1157
1158         smu_v14_0_0_set_smu_mailbox_registers(smu);
1159 }