Merge tag 'char-misc-6.8-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[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                 if ((smu->smc_fw_version > 0x5d4600))
265                         *value = metrics->GfxActivity;
266                 else
267                         *value = metrics->GfxActivity / 100;
268                 break;
269         case METRICS_AVERAGE_VCNACTIVITY:
270                 *value = metrics->VcnActivity / 100;
271                 break;
272         case METRICS_AVERAGE_SOCKETPOWER:
273         case METRICS_CURR_SOCKETPOWER:
274                 *value = (metrics->SocketPower / 1000 << 8) +
275                 (metrics->SocketPower % 1000 / 10);
276                 break;
277         case METRICS_TEMPERATURE_EDGE:
278                 *value = metrics->GfxTemperature / 100 *
279                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
280                 break;
281         case METRICS_TEMPERATURE_HOTSPOT:
282                 *value = metrics->SocTemperature / 100 *
283                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
284                 break;
285         case METRICS_THROTTLER_RESIDENCY_PROCHOT:
286                 *value = metrics->ThrottleResidency_PROCHOT;
287                 break;
288         case METRICS_THROTTLER_RESIDENCY_SPL:
289                 *value = metrics->ThrottleResidency_SPL;
290                 break;
291         case METRICS_THROTTLER_RESIDENCY_FPPT:
292                 *value = metrics->ThrottleResidency_FPPT;
293                 break;
294         case METRICS_THROTTLER_RESIDENCY_SPPT:
295                 *value = metrics->ThrottleResidency_SPPT;
296                 break;
297         case METRICS_THROTTLER_RESIDENCY_THM_CORE:
298                 *value = metrics->ThrottleResidency_THM_CORE;
299                 break;
300         case METRICS_THROTTLER_RESIDENCY_THM_GFX:
301                 *value = metrics->ThrottleResidency_THM_GFX;
302                 break;
303         case METRICS_THROTTLER_RESIDENCY_THM_SOC:
304                 *value = metrics->ThrottleResidency_THM_SOC;
305                 break;
306         case METRICS_VOLTAGE_VDDGFX:
307                 *value = 0;
308                 break;
309         case METRICS_VOLTAGE_VDDSOC:
310                 *value = 0;
311                 break;
312         case METRICS_SS_APU_SHARE:
313                 /* return the percentage of APU power with respect to APU's power limit.
314                  * percentage is reported, this isn't boost value. Smartshift power
315                  * boost/shift is only when the percentage is more than 100.
316                  */
317                 if (metrics->StapmOpnLimit > 0)
318                         *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit;
319                 else
320                         *value = 0;
321                 break;
322         case METRICS_SS_DGPU_SHARE:
323                 /* return the percentage of dGPU power with respect to dGPU's power limit.
324                  * percentage is reported, this isn't boost value. Smartshift power
325                  * boost/shift is only when the percentage is more than 100.
326                  */
327                 if ((metrics->dGpuPower > 0) &&
328                     (metrics->StapmCurrentLimit > metrics->StapmOpnLimit))
329                         *value = (metrics->dGpuPower * 100) /
330                                  (metrics->StapmCurrentLimit - metrics->StapmOpnLimit);
331                 else
332                         *value = 0;
333                 break;
334         default:
335                 *value = UINT_MAX;
336                 break;
337         }
338
339         return ret;
340 }
341
342 static int smu_v14_0_0_read_sensor(struct smu_context *smu,
343                                    enum amd_pp_sensors sensor,
344                                    void *data, uint32_t *size)
345 {
346         int ret = 0;
347
348         if (!data || !size)
349                 return -EINVAL;
350
351         switch (sensor) {
352         case AMDGPU_PP_SENSOR_GPU_LOAD:
353                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
354                                                        METRICS_AVERAGE_GFXACTIVITY,
355                                                        (uint32_t *)data);
356                 *size = 4;
357                 break;
358         case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
359                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
360                                                        METRICS_AVERAGE_SOCKETPOWER,
361                                                        (uint32_t *)data);
362                 *size = 4;
363                 break;
364         case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
365                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
366                                                        METRICS_CURR_SOCKETPOWER,
367                                                        (uint32_t *)data);
368                 *size = 4;
369                 break;
370         case AMDGPU_PP_SENSOR_EDGE_TEMP:
371                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
372                                                        METRICS_TEMPERATURE_EDGE,
373                                                        (uint32_t *)data);
374                 *size = 4;
375                 break;
376         case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
377                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
378                                                        METRICS_TEMPERATURE_HOTSPOT,
379                                                        (uint32_t *)data);
380                 *size = 4;
381                 break;
382         case AMDGPU_PP_SENSOR_GFX_MCLK:
383                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
384                                                        METRICS_AVERAGE_UCLK,
385                                                        (uint32_t *)data);
386                 *(uint32_t *)data *= 100;
387                 *size = 4;
388                 break;
389         case AMDGPU_PP_SENSOR_GFX_SCLK:
390                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
391                                                        METRICS_AVERAGE_GFXCLK,
392                                                        (uint32_t *)data);
393                 *(uint32_t *)data *= 100;
394                 *size = 4;
395                 break;
396         case AMDGPU_PP_SENSOR_VDDGFX:
397                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
398                                                        METRICS_VOLTAGE_VDDGFX,
399                                                        (uint32_t *)data);
400                 *size = 4;
401                 break;
402         case AMDGPU_PP_SENSOR_VDDNB:
403                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
404                                                        METRICS_VOLTAGE_VDDSOC,
405                                                        (uint32_t *)data);
406                 *size = 4;
407                 break;
408         case AMDGPU_PP_SENSOR_SS_APU_SHARE:
409                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
410                                                        METRICS_SS_APU_SHARE,
411                                                        (uint32_t *)data);
412                 *size = 4;
413                 break;
414         case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
415                 ret = smu_v14_0_0_get_smu_metrics_data(smu,
416                                                        METRICS_SS_DGPU_SHARE,
417                                                        (uint32_t *)data);
418                 *size = 4;
419                 break;
420         default:
421                 ret = -EOPNOTSUPP;
422                 break;
423         }
424
425         return ret;
426 }
427
428 static bool smu_v14_0_0_is_dpm_running(struct smu_context *smu)
429 {
430         int ret = 0;
431         uint64_t feature_enabled;
432
433         ret = smu_cmn_get_enabled_mask(smu, &feature_enabled);
434
435         if (ret)
436                 return false;
437
438         return !!(feature_enabled & SMC_DPM_FEATURE);
439 }
440
441 static int smu_v14_0_0_set_watermarks_table(struct smu_context *smu,
442                                             struct pp_smu_wm_range_sets *clock_ranges)
443 {
444         int i;
445         int ret = 0;
446         Watermarks_t *table = smu->smu_table.watermarks_table;
447
448         if (!table || !clock_ranges)
449                 return -EINVAL;
450
451         if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES ||
452                 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES)
453                 return -EINVAL;
454
455         for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
456                 table->WatermarkRow[WM_DCFCLK][i].MinClock =
457                         clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
458                 table->WatermarkRow[WM_DCFCLK][i].MaxClock =
459                         clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
460                 table->WatermarkRow[WM_DCFCLK][i].MinMclk =
461                         clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
462                 table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
463                         clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
464
465                 table->WatermarkRow[WM_DCFCLK][i].WmSetting =
466                         clock_ranges->reader_wm_sets[i].wm_inst;
467         }
468
469         for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
470                 table->WatermarkRow[WM_SOCCLK][i].MinClock =
471                         clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
472                 table->WatermarkRow[WM_SOCCLK][i].MaxClock =
473                         clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
474                 table->WatermarkRow[WM_SOCCLK][i].MinMclk =
475                         clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
476                 table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
477                         clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
478
479                 table->WatermarkRow[WM_SOCCLK][i].WmSetting =
480                         clock_ranges->writer_wm_sets[i].wm_inst;
481         }
482
483         smu->watermarks_bitmap |= WATERMARKS_EXIST;
484
485         /* pass data to smu controller */
486         if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
487              !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
488                 ret = smu_cmn_write_watermarks_table(smu);
489                 if (ret) {
490                         dev_err(smu->adev->dev, "Failed to update WMTABLE!");
491                         return ret;
492                 }
493                 smu->watermarks_bitmap |= WATERMARKS_LOADED;
494         }
495
496         return 0;
497 }
498
499 static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
500                                                 void **table)
501 {
502         struct smu_table_context *smu_table = &smu->smu_table;
503         struct gpu_metrics_v3_0 *gpu_metrics =
504                 (struct gpu_metrics_v3_0 *)smu_table->gpu_metrics_table;
505         SmuMetrics_t metrics;
506         int ret = 0;
507
508         ret = smu_cmn_get_metrics_table(smu, &metrics, true);
509         if (ret)
510                 return ret;
511
512         smu_cmn_init_soft_gpu_metrics(gpu_metrics, 3, 0);
513
514         gpu_metrics->temperature_gfx = metrics.GfxTemperature;
515         gpu_metrics->temperature_soc = metrics.SocTemperature;
516         memcpy(&gpu_metrics->temperature_core[0],
517                 &metrics.CoreTemperature[0],
518                 sizeof(uint16_t) * 16);
519         gpu_metrics->temperature_skin = metrics.SkinTemp;
520
521         gpu_metrics->average_gfx_activity = metrics.GfxActivity;
522         gpu_metrics->average_vcn_activity = metrics.VcnActivity;
523         memcpy(&gpu_metrics->average_ipu_activity[0],
524                 &metrics.IpuBusy[0],
525                 sizeof(uint16_t) * 8);
526         memcpy(&gpu_metrics->average_core_c0_activity[0],
527                 &metrics.CoreC0Residency[0],
528                 sizeof(uint16_t) * 16);
529         gpu_metrics->average_dram_reads = metrics.DRAMReads;
530         gpu_metrics->average_dram_writes = metrics.DRAMWrites;
531         gpu_metrics->average_ipu_reads = metrics.IpuReads;
532         gpu_metrics->average_ipu_writes = metrics.IpuWrites;
533
534         gpu_metrics->average_socket_power = metrics.SocketPower;
535         gpu_metrics->average_ipu_power = metrics.IpuPower;
536         gpu_metrics->average_apu_power = metrics.ApuPower;
537         gpu_metrics->average_gfx_power = metrics.GfxPower;
538         gpu_metrics->average_dgpu_power = metrics.dGpuPower;
539         gpu_metrics->average_all_core_power = metrics.AllCorePower;
540         gpu_metrics->average_sys_power = metrics.Psys;
541         memcpy(&gpu_metrics->average_core_power[0],
542                 &metrics.CorePower[0],
543                 sizeof(uint16_t) * 16);
544
545         gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency;
546         gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency;
547         gpu_metrics->average_vpeclk_frequency = metrics.VpeclkFrequency;
548         gpu_metrics->average_fclk_frequency = metrics.FclkFrequency;
549         gpu_metrics->average_vclk_frequency = metrics.VclkFrequency;
550         gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency;
551         gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency;
552         gpu_metrics->average_mpipu_frequency = metrics.MpipuclkFrequency;
553
554         memcpy(&gpu_metrics->current_coreclk[0],
555                 &metrics.CoreFrequency[0],
556                 sizeof(uint16_t) * 16);
557         gpu_metrics->current_core_maxfreq = metrics.InfrastructureCpuMaxFreq;
558         gpu_metrics->current_gfx_maxfreq = metrics.InfrastructureGfxMaxFreq;
559
560         gpu_metrics->throttle_residency_prochot = metrics.ThrottleResidency_PROCHOT;
561         gpu_metrics->throttle_residency_spl = metrics.ThrottleResidency_SPL;
562         gpu_metrics->throttle_residency_fppt = metrics.ThrottleResidency_FPPT;
563         gpu_metrics->throttle_residency_sppt = metrics.ThrottleResidency_SPPT;
564         gpu_metrics->throttle_residency_thm_core = metrics.ThrottleResidency_THM_CORE;
565         gpu_metrics->throttle_residency_thm_gfx = metrics.ThrottleResidency_THM_GFX;
566         gpu_metrics->throttle_residency_thm_soc = metrics.ThrottleResidency_THM_SOC;
567
568         gpu_metrics->time_filter_alphavalue = metrics.FilterAlphaValue;
569         gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
570
571         *table = (void *)gpu_metrics;
572
573         return sizeof(struct gpu_metrics_v3_0);
574 }
575
576 static int smu_v14_0_0_mode2_reset(struct smu_context *smu)
577 {
578         int ret;
579
580         ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset,
581                                                SMU_RESET_MODE_2, NULL);
582
583         if (ret)
584                 dev_err(smu->adev->dev, "Failed to mode2 reset!\n");
585
586         return ret;
587 }
588
589 static int smu_v14_0_0_get_dpm_freq_by_index(struct smu_context *smu,
590                                                 enum smu_clk_type clk_type,
591                                                 uint32_t dpm_level,
592                                                 uint32_t *freq)
593 {
594         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
595
596         if (!clk_table || clk_type >= SMU_CLK_COUNT)
597                 return -EINVAL;
598
599         switch (clk_type) {
600         case SMU_SOCCLK:
601                 if (dpm_level >= clk_table->NumSocClkLevelsEnabled)
602                         return -EINVAL;
603                 *freq = clk_table->SocClocks[dpm_level];
604                 break;
605         case SMU_VCLK:
606                 if (dpm_level >= clk_table->VcnClkLevelsEnabled)
607                         return -EINVAL;
608                 *freq = clk_table->VClocks[dpm_level];
609                 break;
610         case SMU_DCLK:
611                 if (dpm_level >= clk_table->VcnClkLevelsEnabled)
612                         return -EINVAL;
613                 *freq = clk_table->DClocks[dpm_level];
614                 break;
615         case SMU_UCLK:
616         case SMU_MCLK:
617                 if (dpm_level >= clk_table->NumMemPstatesEnabled)
618                         return -EINVAL;
619                 *freq = clk_table->MemPstateTable[dpm_level].MemClk;
620                 break;
621         case SMU_FCLK:
622                 if (dpm_level >= clk_table->NumFclkLevelsEnabled)
623                         return -EINVAL;
624                 *freq = clk_table->FclkClocks_Freq[dpm_level];
625                 break;
626         default:
627                 return -EINVAL;
628         }
629
630         return 0;
631 }
632
633 static bool smu_v14_0_0_clk_dpm_is_enabled(struct smu_context *smu,
634                                                 enum smu_clk_type clk_type)
635 {
636         enum smu_feature_mask feature_id = 0;
637
638         switch (clk_type) {
639         case SMU_MCLK:
640         case SMU_UCLK:
641         case SMU_FCLK:
642                 feature_id = SMU_FEATURE_DPM_FCLK_BIT;
643                 break;
644         case SMU_GFXCLK:
645         case SMU_SCLK:
646                 feature_id = SMU_FEATURE_DPM_GFXCLK_BIT;
647                 break;
648         case SMU_SOCCLK:
649                 feature_id = SMU_FEATURE_DPM_SOCCLK_BIT;
650                 break;
651         case SMU_VCLK:
652         case SMU_DCLK:
653                 feature_id = SMU_FEATURE_VCN_DPM_BIT;
654                 break;
655         default:
656                 return true;
657         }
658
659         return smu_cmn_feature_is_enabled(smu, feature_id);
660 }
661
662 static int smu_v14_0_0_get_dpm_ultimate_freq(struct smu_context *smu,
663                                                         enum smu_clk_type clk_type,
664                                                         uint32_t *min,
665                                                         uint32_t *max)
666 {
667         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
668         uint32_t clock_limit;
669         uint32_t max_dpm_level, min_dpm_level;
670         int ret = 0;
671
672         if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) {
673                 switch (clk_type) {
674                 case SMU_MCLK:
675                 case SMU_UCLK:
676                         clock_limit = smu->smu_table.boot_values.uclk;
677                         break;
678                 case SMU_FCLK:
679                         clock_limit = smu->smu_table.boot_values.fclk;
680                         break;
681                 case SMU_GFXCLK:
682                 case SMU_SCLK:
683                         clock_limit = smu->smu_table.boot_values.gfxclk;
684                         break;
685                 case SMU_SOCCLK:
686                         clock_limit = smu->smu_table.boot_values.socclk;
687                         break;
688                 case SMU_VCLK:
689                         clock_limit = smu->smu_table.boot_values.vclk;
690                         break;
691                 case SMU_DCLK:
692                         clock_limit = smu->smu_table.boot_values.dclk;
693                         break;
694                 default:
695                         clock_limit = 0;
696                         break;
697                 }
698
699                 /* clock in Mhz unit */
700                 if (min)
701                         *min = clock_limit / 100;
702                 if (max)
703                         *max = clock_limit / 100;
704
705                 return 0;
706         }
707
708         if (max) {
709                 switch (clk_type) {
710                 case SMU_GFXCLK:
711                 case SMU_SCLK:
712                         *max = clk_table->MaxGfxClk;
713                         break;
714                 case SMU_MCLK:
715                 case SMU_UCLK:
716                 case SMU_FCLK:
717                         max_dpm_level = 0;
718                         break;
719                 case SMU_SOCCLK:
720                         max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1;
721                         break;
722                 case SMU_VCLK:
723                 case SMU_DCLK:
724                         max_dpm_level = clk_table->VcnClkLevelsEnabled - 1;
725                         break;
726                 default:
727                         ret = -EINVAL;
728                         goto failed;
729                 }
730
731                 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
732                         ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, max_dpm_level, max);
733                         if (ret)
734                                 goto failed;
735                 }
736         }
737
738         if (min) {
739                 switch (clk_type) {
740                 case SMU_GFXCLK:
741                 case SMU_SCLK:
742                         *min = clk_table->MinGfxClk;
743                         break;
744                 case SMU_MCLK:
745                 case SMU_UCLK:
746                         min_dpm_level = clk_table->NumMemPstatesEnabled - 1;
747                         break;
748                 case SMU_FCLK:
749                         min_dpm_level = clk_table->NumFclkLevelsEnabled - 1;
750                         break;
751                 case SMU_SOCCLK:
752                         min_dpm_level = 0;
753                         break;
754                 case SMU_VCLK:
755                 case SMU_DCLK:
756                         min_dpm_level = 0;
757                         break;
758                 default:
759                         ret = -EINVAL;
760                         goto failed;
761                 }
762
763                 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
764                         ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, min_dpm_level, min);
765                         if (ret)
766                                 goto failed;
767                 }
768         }
769
770 failed:
771         return ret;
772 }
773
774 static int smu_v14_0_0_get_current_clk_freq(struct smu_context *smu,
775                                             enum smu_clk_type clk_type,
776                                             uint32_t *value)
777 {
778         MetricsMember_t member_type;
779
780         switch (clk_type) {
781         case SMU_SOCCLK:
782                 member_type = METRICS_AVERAGE_SOCCLK;
783                 break;
784         case SMU_VCLK:
785                 member_type = METRICS_AVERAGE_VCLK;
786                 break;
787         case SMU_DCLK:
788                 member_type = METRICS_AVERAGE_DCLK;
789                 break;
790         case SMU_MCLK:
791                 member_type = METRICS_AVERAGE_UCLK;
792                 break;
793         case SMU_FCLK:
794                 member_type = METRICS_AVERAGE_FCLK;
795                 break;
796         case SMU_GFXCLK:
797         case SMU_SCLK:
798                 member_type = METRICS_AVERAGE_GFXCLK;
799                 break;
800         default:
801                 return -EINVAL;
802         }
803
804         return smu_v14_0_0_get_smu_metrics_data(smu, member_type, value);
805 }
806
807 static int smu_v14_0_0_get_dpm_level_count(struct smu_context *smu,
808                                            enum smu_clk_type clk_type,
809                                            uint32_t *count)
810 {
811         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
812
813         switch (clk_type) {
814         case SMU_SOCCLK:
815                 *count = clk_table->NumSocClkLevelsEnabled;
816                 break;
817         case SMU_VCLK:
818                 *count = clk_table->VcnClkLevelsEnabled;
819                 break;
820         case SMU_DCLK:
821                 *count = clk_table->VcnClkLevelsEnabled;
822                 break;
823         case SMU_MCLK:
824                 *count = clk_table->NumMemPstatesEnabled;
825                 break;
826         case SMU_FCLK:
827                 *count = clk_table->NumFclkLevelsEnabled;
828                 break;
829         default:
830                 break;
831         }
832
833         return 0;
834 }
835
836 static int smu_v14_0_0_print_clk_levels(struct smu_context *smu,
837                                         enum smu_clk_type clk_type, char *buf)
838 {
839         int i, size = 0, ret = 0;
840         uint32_t cur_value = 0, value = 0, count = 0;
841         uint32_t min, max;
842
843         smu_cmn_get_sysfs_buf(&buf, &size);
844
845         switch (clk_type) {
846         case SMU_OD_SCLK:
847                 size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
848                 size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
849                 (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq);
850                 size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
851                 (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq);
852                 break;
853         case SMU_OD_RANGE:
854                 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
855                 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
856                                       smu->gfx_default_hard_min_freq,
857                                       smu->gfx_default_soft_max_freq);
858                 break;
859         case SMU_SOCCLK:
860         case SMU_VCLK:
861         case SMU_DCLK:
862         case SMU_MCLK:
863         case SMU_FCLK:
864                 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value);
865                 if (ret)
866                         break;
867
868                 ret = smu_v14_0_0_get_dpm_level_count(smu, clk_type, &count);
869                 if (ret)
870                         break;
871
872                 for (i = 0; i < count; i++) {
873                         ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
874                         if (ret)
875                                 break;
876
877                         size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value,
878                                               cur_value == value ? "*" : "");
879                 }
880                 break;
881         case SMU_GFXCLK:
882         case SMU_SCLK:
883                 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value);
884                 if (ret)
885                         break;
886                 min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
887                 max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
888                 if (cur_value  == max)
889                         i = 2;
890                 else if (cur_value == min)
891                         i = 0;
892                 else
893                         i = 1;
894                 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
895                                       i == 0 ? "*" : "");
896                 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
897                                       i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */
898                                       i == 1 ? "*" : "");
899                 size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
900                                       i == 2 ? "*" : "");
901                 break;
902         default:
903                 break;
904         }
905
906         return size;
907 }
908
909 static int smu_v14_0_0_set_soft_freq_limited_range(struct smu_context *smu,
910                                                    enum smu_clk_type clk_type,
911                                                    uint32_t min,
912                                                    uint32_t max)
913 {
914         enum smu_message_type msg_set_min, msg_set_max;
915         int ret = 0;
916
917         if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type))
918                 return -EINVAL;
919
920         switch (clk_type) {
921         case SMU_GFXCLK:
922         case SMU_SCLK:
923                 msg_set_min = SMU_MSG_SetHardMinGfxClk;
924                 msg_set_max = SMU_MSG_SetSoftMaxGfxClk;
925                 break;
926         case SMU_FCLK:
927                 msg_set_min = SMU_MSG_SetHardMinFclkByFreq;
928                 msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq;
929                 break;
930         case SMU_SOCCLK:
931                 msg_set_min = SMU_MSG_SetHardMinSocclkByFreq;
932                 msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq;
933                 break;
934         case SMU_VCLK:
935         case SMU_DCLK:
936                 msg_set_min = SMU_MSG_SetHardMinVcn;
937                 msg_set_max = SMU_MSG_SetSoftMaxVcn;
938                 break;
939         default:
940                 return -EINVAL;
941         }
942
943         ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_min, min, NULL);
944         if (ret)
945                 return ret;
946
947         return smu_cmn_send_smc_msg_with_param(smu, msg_set_max,
948                                                max, NULL);
949 }
950
951 static int smu_v14_0_0_force_clk_levels(struct smu_context *smu,
952                                         enum smu_clk_type clk_type,
953                                         uint32_t mask)
954 {
955         uint32_t soft_min_level = 0, soft_max_level = 0;
956         uint32_t min_freq = 0, max_freq = 0;
957         int ret = 0;
958
959         soft_min_level = mask ? (ffs(mask) - 1) : 0;
960         soft_max_level = mask ? (fls(mask) - 1) : 0;
961
962         switch (clk_type) {
963         case SMU_SOCCLK:
964         case SMU_FCLK:
965         case SMU_VCLK:
966         case SMU_DCLK:
967                 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq);
968                 if (ret)
969                         break;
970
971                 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq);
972                 if (ret)
973                         break;
974
975                 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
976                 break;
977         default:
978                 ret = -EINVAL;
979                 break;
980         }
981
982         return ret;
983 }
984
985 static int smu_v14_0_0_set_performance_level(struct smu_context *smu,
986                                              enum amd_dpm_forced_level level)
987 {
988         struct amdgpu_device *adev = smu->adev;
989         uint32_t sclk_min = 0, sclk_max = 0;
990         uint32_t fclk_min = 0, fclk_max = 0;
991         uint32_t socclk_min = 0, socclk_max = 0;
992         int ret = 0;
993
994         switch (level) {
995         case AMD_DPM_FORCED_LEVEL_HIGH:
996                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_max);
997                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_max);
998                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_max);
999                 sclk_min = sclk_max;
1000                 fclk_min = fclk_max;
1001                 socclk_min = socclk_max;
1002                 break;
1003         case AMD_DPM_FORCED_LEVEL_LOW:
1004                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, NULL);
1005                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, NULL);
1006                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, NULL);
1007                 sclk_max = sclk_min;
1008                 fclk_max = fclk_min;
1009                 socclk_max = socclk_min;
1010                 break;
1011         case AMD_DPM_FORCED_LEVEL_AUTO:
1012                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, &sclk_max);
1013                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, &fclk_max);
1014                 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, &socclk_max);
1015                 break;
1016         case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1017         case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1018         case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1019         case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1020                 /* Temporarily do nothing since the optimal clocks haven't been provided yet */
1021                 break;
1022         case AMD_DPM_FORCED_LEVEL_MANUAL:
1023         case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
1024                 return 0;
1025         default:
1026                 dev_err(adev->dev, "Invalid performance level %d\n", level);
1027                 return -EINVAL;
1028         }
1029
1030         if (sclk_min && sclk_max) {
1031                 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1032                                                               SMU_SCLK,
1033                                                               sclk_min,
1034                                                               sclk_max);
1035                 if (ret)
1036                         return ret;
1037
1038                 smu->gfx_actual_hard_min_freq = sclk_min;
1039                 smu->gfx_actual_soft_max_freq = sclk_max;
1040         }
1041
1042         if (fclk_min && fclk_max) {
1043                 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1044                                                               SMU_FCLK,
1045                                                               fclk_min,
1046                                                               fclk_max);
1047                 if (ret)
1048                         return ret;
1049         }
1050
1051         if (socclk_min && socclk_max) {
1052                 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1053                                                               SMU_SOCCLK,
1054                                                               socclk_min,
1055                                                               socclk_max);
1056                 if (ret)
1057                         return ret;
1058         }
1059
1060         return ret;
1061 }
1062
1063 static int smu_v14_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
1064 {
1065         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
1066
1067         smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
1068         smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
1069         smu->gfx_actual_hard_min_freq = 0;
1070         smu->gfx_actual_soft_max_freq = 0;
1071
1072         return 0;
1073 }
1074
1075 static int smu_v14_0_0_set_vpe_enable(struct smu_context *smu,
1076                                       bool enable)
1077 {
1078         return smu_cmn_send_smc_msg_with_param(smu, enable ?
1079                                                SMU_MSG_PowerUpVpe : SMU_MSG_PowerDownVpe,
1080                                                0, NULL);
1081 }
1082
1083 static int smu_v14_0_0_set_umsch_mm_enable(struct smu_context *smu,
1084                               bool enable)
1085 {
1086         return smu_cmn_send_smc_msg_with_param(smu, enable ?
1087                                                SMU_MSG_PowerUpUmsch : SMU_MSG_PowerDownUmsch,
1088                                                0, NULL);
1089 }
1090
1091 static int smu_14_0_0_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
1092 {
1093         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
1094         uint8_t idx;
1095
1096         /* Only the Clock information of SOC and VPE is copied to provide VPE DPM settings for use. */
1097         for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) {
1098                 clock_table->SocClocks[idx].Freq = (idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0;
1099                 clock_table->SocClocks[idx].Vol = 0;
1100         }
1101
1102         for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) {
1103                 clock_table->VPEClocks[idx].Freq = (idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0;
1104                 clock_table->VPEClocks[idx].Vol = 0;
1105         }
1106
1107         return 0;
1108 }
1109
1110 static const struct pptable_funcs smu_v14_0_0_ppt_funcs = {
1111         .check_fw_status = smu_v14_0_check_fw_status,
1112         .check_fw_version = smu_v14_0_check_fw_version,
1113         .init_smc_tables = smu_v14_0_0_init_smc_tables,
1114         .fini_smc_tables = smu_v14_0_0_fini_smc_tables,
1115         .get_vbios_bootup_values = smu_v14_0_get_vbios_bootup_values,
1116         .system_features_control = smu_v14_0_0_system_features_control,
1117         .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
1118         .send_smc_msg = smu_cmn_send_smc_msg,
1119         .dpm_set_vcn_enable = smu_v14_0_set_vcn_enable,
1120         .dpm_set_jpeg_enable = smu_v14_0_set_jpeg_enable,
1121         .set_default_dpm_table = smu_v14_0_set_default_dpm_tables,
1122         .read_sensor = smu_v14_0_0_read_sensor,
1123         .is_dpm_running = smu_v14_0_0_is_dpm_running,
1124         .set_watermarks_table = smu_v14_0_0_set_watermarks_table,
1125         .get_gpu_metrics = smu_v14_0_0_get_gpu_metrics,
1126         .get_enabled_mask = smu_cmn_get_enabled_mask,
1127         .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
1128         .set_driver_table_location = smu_v14_0_set_driver_table_location,
1129         .gfx_off_control = smu_v14_0_gfx_off_control,
1130         .mode2_reset = smu_v14_0_0_mode2_reset,
1131         .get_dpm_ultimate_freq = smu_v14_0_0_get_dpm_ultimate_freq,
1132         .od_edit_dpm_table = smu_v14_0_od_edit_dpm_table,
1133         .print_clk_levels = smu_v14_0_0_print_clk_levels,
1134         .force_clk_levels = smu_v14_0_0_force_clk_levels,
1135         .set_performance_level = smu_v14_0_0_set_performance_level,
1136         .set_fine_grain_gfx_freq_parameters = smu_v14_0_0_set_fine_grain_gfx_freq_parameters,
1137         .set_gfx_power_up_by_imu = smu_v14_0_set_gfx_power_up_by_imu,
1138         .dpm_set_vpe_enable = smu_v14_0_0_set_vpe_enable,
1139         .dpm_set_umsch_mm_enable = smu_v14_0_0_set_umsch_mm_enable,
1140         .get_dpm_clock_table = smu_14_0_0_get_dpm_table,
1141 };
1142
1143 static void smu_v14_0_0_set_smu_mailbox_registers(struct smu_context *smu)
1144 {
1145         struct amdgpu_device *adev = smu->adev;
1146
1147         smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82);
1148         smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66);
1149         smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
1150 }
1151
1152 void smu_v14_0_0_set_ppt_funcs(struct smu_context *smu)
1153 {
1154
1155         smu->ppt_funcs = &smu_v14_0_0_ppt_funcs;
1156         smu->message_map = smu_v14_0_0_message_map;
1157         smu->feature_map = smu_v14_0_0_feature_mask_map;
1158         smu->table_map = smu_v14_0_0_table_map;
1159         smu->is_apu = true;
1160
1161         smu_v14_0_0_set_smu_mailbox_registers(smu);
1162 }