Merge tag '5.3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
[linux-2.6-block.git] / drivers / gpu / drm / amd / powerplay / amdgpu_smu.c
1 /*
2  * Copyright 2019 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  */
22
23 #include <linux/firmware.h>
24
25 #include "pp_debug.h"
26 #include "amdgpu.h"
27 #include "amdgpu_smu.h"
28 #include "soc15_common.h"
29 #include "smu_v11_0.h"
30 #include "atom.h"
31 #include "amd_pcie.h"
32
33 int smu_get_smc_version(struct smu_context *smu, uint32_t *if_version, uint32_t *smu_version)
34 {
35         int ret = 0;
36
37         if (!if_version && !smu_version)
38                 return -EINVAL;
39
40         if (if_version) {
41                 ret = smu_send_smc_msg(smu, SMU_MSG_GetDriverIfVersion);
42                 if (ret)
43                         return ret;
44
45                 ret = smu_read_smc_arg(smu, if_version);
46                 if (ret)
47                         return ret;
48         }
49
50         if (smu_version) {
51                 ret = smu_send_smc_msg(smu, SMU_MSG_GetSmuVersion);
52                 if (ret)
53                         return ret;
54
55                 ret = smu_read_smc_arg(smu, smu_version);
56                 if (ret)
57                         return ret;
58         }
59
60         return ret;
61 }
62
63 int smu_set_soft_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
64                             uint32_t min, uint32_t max)
65 {
66         int ret = 0, clk_id = 0;
67         uint32_t param;
68
69         if (min <= 0 && max <= 0)
70                 return -EINVAL;
71
72         if (!smu_clk_dpm_is_enabled(smu, clk_type))
73                 return 0;
74
75         clk_id = smu_clk_get_index(smu, clk_type);
76         if (clk_id < 0)
77                 return clk_id;
78
79         if (max > 0) {
80                 param = (uint32_t)((clk_id << 16) | (max & 0xffff));
81                 ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq,
82                                                   param);
83                 if (ret)
84                         return ret;
85         }
86
87         if (min > 0) {
88                 param = (uint32_t)((clk_id << 16) | (min & 0xffff));
89                 ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq,
90                                                   param);
91                 if (ret)
92                         return ret;
93         }
94
95
96         return ret;
97 }
98
99 int smu_set_hard_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
100                             uint32_t min, uint32_t max)
101 {
102         int ret = 0, clk_id = 0;
103         uint32_t param;
104
105         if (min <= 0 && max <= 0)
106                 return -EINVAL;
107
108         if (!smu_clk_dpm_is_enabled(smu, clk_type))
109                 return 0;
110
111         clk_id = smu_clk_get_index(smu, clk_type);
112         if (clk_id < 0)
113                 return clk_id;
114
115         if (max > 0) {
116                 param = (uint32_t)((clk_id << 16) | (max & 0xffff));
117                 ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMaxByFreq,
118                                                   param);
119                 if (ret)
120                         return ret;
121         }
122
123         if (min > 0) {
124                 param = (uint32_t)((clk_id << 16) | (min & 0xffff));
125                 ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq,
126                                                   param);
127                 if (ret)
128                         return ret;
129         }
130
131
132         return ret;
133 }
134
135 int smu_get_dpm_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
136                            uint32_t *min, uint32_t *max)
137 {
138         int ret = 0, clk_id = 0;
139         uint32_t param = 0;
140
141         if (!min && !max)
142                 return -EINVAL;
143
144         if (!smu_clk_dpm_is_enabled(smu, clk_type))
145                 return 0;
146
147         mutex_lock(&smu->mutex);
148         clk_id = smu_clk_get_index(smu, clk_type);
149         if (clk_id < 0) {
150                 ret = -EINVAL;
151                 goto failed;
152         }
153
154         param = (clk_id & 0xffff) << 16;
155
156         if (max) {
157                 ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq, param);
158                 if (ret)
159                         goto failed;
160                 ret = smu_read_smc_arg(smu, max);
161                 if (ret)
162                         goto failed;
163         }
164
165         if (min) {
166                 ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq, param);
167                 if (ret)
168                         goto failed;
169                 ret = smu_read_smc_arg(smu, min);
170                 if (ret)
171                         goto failed;
172         }
173
174 failed:
175         mutex_unlock(&smu->mutex);
176         return ret;
177 }
178
179 int smu_get_dpm_freq_by_index(struct smu_context *smu, enum smu_clk_type clk_type,
180                               uint16_t level, uint32_t *value)
181 {
182         int ret = 0, clk_id = 0;
183         uint32_t param;
184
185         if (!value)
186                 return -EINVAL;
187
188         if (!smu_clk_dpm_is_enabled(smu, clk_type))
189                 return 0;
190
191         clk_id = smu_clk_get_index(smu, clk_type);
192         if (clk_id < 0)
193                 return clk_id;
194
195         param = (uint32_t)(((clk_id & 0xffff) << 16) | (level & 0xffff));
196
197         ret = smu_send_smc_msg_with_param(smu,SMU_MSG_GetDpmFreqByIndex,
198                                           param);
199         if (ret)
200                 return ret;
201
202         ret = smu_read_smc_arg(smu, &param);
203         if (ret)
204                 return ret;
205
206         /* BIT31:  0 - Fine grained DPM, 1 - Dicrete DPM
207          * now, we un-support it */
208         *value = param & 0x7fffffff;
209
210         return ret;
211 }
212
213 int smu_get_dpm_level_count(struct smu_context *smu, enum smu_clk_type clk_type,
214                             uint32_t *value)
215 {
216         return smu_get_dpm_freq_by_index(smu, clk_type, 0xff, value);
217 }
218
219 bool smu_clk_dpm_is_enabled(struct smu_context *smu, enum smu_clk_type clk_type)
220 {
221         enum smu_feature_mask feature_id = 0;
222
223         switch (clk_type) {
224         case SMU_MCLK:
225         case SMU_UCLK:
226                 feature_id = SMU_FEATURE_DPM_UCLK_BIT;
227                 break;
228         case SMU_GFXCLK:
229         case SMU_SCLK:
230                 feature_id = SMU_FEATURE_DPM_GFXCLK_BIT;
231                 break;
232         case SMU_SOCCLK:
233                 feature_id = SMU_FEATURE_DPM_SOCCLK_BIT;
234                 break;
235         default:
236                 return true;
237         }
238
239         if(!smu_feature_is_enabled(smu, feature_id)) {
240                 pr_warn("smu %d clk dpm feature %d is not enabled\n", clk_type, feature_id);
241                 return false;
242         }
243
244         return true;
245 }
246
247
248 int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type,
249                            bool gate)
250 {
251         int ret = 0;
252
253         switch (block_type) {
254         case AMD_IP_BLOCK_TYPE_UVD:
255                 ret = smu_dpm_set_uvd_enable(smu, gate);
256                 break;
257         case AMD_IP_BLOCK_TYPE_VCE:
258                 ret = smu_dpm_set_vce_enable(smu, gate);
259                 break;
260         case AMD_IP_BLOCK_TYPE_GFX:
261                 ret = smu_gfx_off_control(smu, gate);
262                 break;
263         default:
264                 break;
265         }
266
267         return ret;
268 }
269
270 enum amd_pm_state_type smu_get_current_power_state(struct smu_context *smu)
271 {
272         /* not support power state */
273         return POWER_STATE_TYPE_DEFAULT;
274 }
275
276 int smu_get_power_num_states(struct smu_context *smu,
277                              struct pp_states_info *state_info)
278 {
279         if (!state_info)
280                 return -EINVAL;
281
282         /* not support power state */
283         memset(state_info, 0, sizeof(struct pp_states_info));
284         state_info->nums = 0;
285
286         return 0;
287 }
288
289 int smu_common_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor,
290                            void *data, uint32_t *size)
291 {
292         int ret = 0;
293
294         switch (sensor) {
295         case AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK:
296                 *((uint32_t *)data) = smu->pstate_sclk;
297                 *size = 4;
298                 break;
299         case AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK:
300                 *((uint32_t *)data) = smu->pstate_mclk;
301                 *size = 4;
302                 break;
303         case AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK:
304                 ret = smu_feature_get_enabled_mask(smu, (uint32_t *)data, 2);
305                 *size = 8;
306                 break;
307         case AMDGPU_PP_SENSOR_UVD_POWER:
308                 *(uint32_t *)data = smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UVD_BIT) ? 1 : 0;
309                 *size = 4;
310                 break;
311         case AMDGPU_PP_SENSOR_VCE_POWER:
312                 *(uint32_t *)data = smu_feature_is_enabled(smu, SMU_FEATURE_DPM_VCE_BIT) ? 1 : 0;
313                 *size = 4;
314                 break;
315         default:
316                 ret = -EINVAL;
317                 break;
318         }
319
320         if (ret)
321                 *size = 0;
322
323         return ret;
324 }
325
326 int smu_update_table(struct smu_context *smu, enum smu_table_id table_index, int argument,
327                      void *table_data, bool drv2smu)
328 {
329         struct smu_table_context *smu_table = &smu->smu_table;
330         struct smu_table *table = NULL;
331         int ret = 0;
332         int table_id = smu_table_get_index(smu, table_index);
333
334         if (!table_data || table_id >= smu_table->table_count)
335                 return -EINVAL;
336
337         table = &smu_table->tables[table_index];
338
339         if (drv2smu)
340                 memcpy(table->cpu_addr, table_data, table->size);
341
342         ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrHigh,
343                                           upper_32_bits(table->mc_address));
344         if (ret)
345                 return ret;
346         ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrLow,
347                                           lower_32_bits(table->mc_address));
348         if (ret)
349                 return ret;
350         ret = smu_send_smc_msg_with_param(smu, drv2smu ?
351                                           SMU_MSG_TransferTableDram2Smu :
352                                           SMU_MSG_TransferTableSmu2Dram,
353                                           table_id | ((argument & 0xFFFF) << 16));
354         if (ret)
355                 return ret;
356
357         if (!drv2smu)
358                 memcpy(table_data, table->cpu_addr, table->size);
359
360         return ret;
361 }
362
363 bool is_support_sw_smu(struct amdgpu_device *adev)
364 {
365         if (adev->asic_type == CHIP_VEGA20)
366                 return (amdgpu_dpm == 2) ? true : false;
367         else if (adev->asic_type >= CHIP_NAVI10)
368                 return true;
369         else
370                 return false;
371 }
372
373 int smu_sys_get_pp_table(struct smu_context *smu, void **table)
374 {
375         struct smu_table_context *smu_table = &smu->smu_table;
376
377         if (!smu_table->power_play_table && !smu_table->hardcode_pptable)
378                 return -EINVAL;
379
380         if (smu_table->hardcode_pptable)
381                 *table = smu_table->hardcode_pptable;
382         else
383                 *table = smu_table->power_play_table;
384
385         return smu_table->power_play_table_size;
386 }
387
388 int smu_sys_set_pp_table(struct smu_context *smu,  void *buf, size_t size)
389 {
390         struct smu_table_context *smu_table = &smu->smu_table;
391         ATOM_COMMON_TABLE_HEADER *header = (ATOM_COMMON_TABLE_HEADER *)buf;
392         int ret = 0;
393
394         if (!smu->pm_enabled)
395                 return -EINVAL;
396         if (header->usStructureSize != size) {
397                 pr_err("pp table size not matched !\n");
398                 return -EIO;
399         }
400
401         mutex_lock(&smu->mutex);
402         if (!smu_table->hardcode_pptable)
403                 smu_table->hardcode_pptable = kzalloc(size, GFP_KERNEL);
404         if (!smu_table->hardcode_pptable) {
405                 ret = -ENOMEM;
406                 goto failed;
407         }
408
409         memcpy(smu_table->hardcode_pptable, buf, size);
410         smu_table->power_play_table = smu_table->hardcode_pptable;
411         smu_table->power_play_table_size = size;
412         mutex_unlock(&smu->mutex);
413
414         ret = smu_reset(smu);
415         if (ret)
416                 pr_info("smu reset failed, ret = %d\n", ret);
417
418         return ret;
419
420 failed:
421         mutex_unlock(&smu->mutex);
422         return ret;
423 }
424
425 int smu_feature_init_dpm(struct smu_context *smu)
426 {
427         struct smu_feature *feature = &smu->smu_feature;
428         int ret = 0;
429         uint32_t allowed_feature_mask[SMU_FEATURE_MAX/32];
430
431         if (!smu->pm_enabled)
432                 return ret;
433         mutex_lock(&feature->mutex);
434         bitmap_zero(feature->allowed, SMU_FEATURE_MAX);
435         mutex_unlock(&feature->mutex);
436
437         ret = smu_get_allowed_feature_mask(smu, allowed_feature_mask,
438                                              SMU_FEATURE_MAX/32);
439         if (ret)
440                 return ret;
441
442         mutex_lock(&feature->mutex);
443         bitmap_or(feature->allowed, feature->allowed,
444                       (unsigned long *)allowed_feature_mask,
445                       feature->feature_num);
446         mutex_unlock(&feature->mutex);
447
448         return ret;
449 }
450
451 int smu_feature_is_enabled(struct smu_context *smu, enum smu_feature_mask mask)
452 {
453         struct smu_feature *feature = &smu->smu_feature;
454         uint32_t feature_id;
455         int ret = 0;
456
457         feature_id = smu_feature_get_index(smu, mask);
458
459         WARN_ON(feature_id > feature->feature_num);
460
461         mutex_lock(&feature->mutex);
462         ret = test_bit(feature_id, feature->enabled);
463         mutex_unlock(&feature->mutex);
464
465         return ret;
466 }
467
468 int smu_feature_set_enabled(struct smu_context *smu, enum smu_feature_mask mask,
469                             bool enable)
470 {
471         struct smu_feature *feature = &smu->smu_feature;
472         uint32_t feature_id;
473         int ret = 0;
474
475         feature_id = smu_feature_get_index(smu, mask);
476
477         WARN_ON(feature_id > feature->feature_num);
478
479         mutex_lock(&feature->mutex);
480         ret = smu_feature_update_enable_state(smu, feature_id, enable);
481         if (ret)
482                 goto failed;
483
484         if (enable)
485                 test_and_set_bit(feature_id, feature->enabled);
486         else
487                 test_and_clear_bit(feature_id, feature->enabled);
488
489 failed:
490         mutex_unlock(&feature->mutex);
491
492         return ret;
493 }
494
495 int smu_feature_is_supported(struct smu_context *smu, enum smu_feature_mask mask)
496 {
497         struct smu_feature *feature = &smu->smu_feature;
498         uint32_t feature_id;
499         int ret = 0;
500
501         feature_id = smu_feature_get_index(smu, mask);
502
503         WARN_ON(feature_id > feature->feature_num);
504
505         mutex_lock(&feature->mutex);
506         ret = test_bit(feature_id, feature->supported);
507         mutex_unlock(&feature->mutex);
508
509         return ret;
510 }
511
512 int smu_feature_set_supported(struct smu_context *smu,
513                               enum smu_feature_mask mask,
514                               bool enable)
515 {
516         struct smu_feature *feature = &smu->smu_feature;
517         uint32_t feature_id;
518         int ret = 0;
519
520         feature_id = smu_feature_get_index(smu, mask);
521
522         WARN_ON(feature_id > feature->feature_num);
523
524         mutex_lock(&feature->mutex);
525         if (enable)
526                 test_and_set_bit(feature_id, feature->supported);
527         else
528                 test_and_clear_bit(feature_id, feature->supported);
529         mutex_unlock(&feature->mutex);
530
531         return ret;
532 }
533
534 static int smu_set_funcs(struct amdgpu_device *adev)
535 {
536         struct smu_context *smu = &adev->smu;
537
538         switch (adev->asic_type) {
539         case CHIP_VEGA20:
540         case CHIP_NAVI10:
541                 if (adev->pm.pp_feature & PP_OVERDRIVE_MASK)
542                         smu->od_enabled = true;
543                 smu_v11_0_set_smu_funcs(smu);
544                 break;
545         default:
546                 return -EINVAL;
547         }
548
549         return 0;
550 }
551
552 static int smu_early_init(void *handle)
553 {
554         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
555         struct smu_context *smu = &adev->smu;
556
557         smu->adev = adev;
558         smu->pm_enabled = !!amdgpu_dpm;
559         mutex_init(&smu->mutex);
560
561         return smu_set_funcs(adev);
562 }
563
564 static int smu_late_init(void *handle)
565 {
566         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
567         struct smu_context *smu = &adev->smu;
568
569         if (!smu->pm_enabled)
570                 return 0;
571         mutex_lock(&smu->mutex);
572         smu_handle_task(&adev->smu,
573                         smu->smu_dpm.dpm_level,
574                         AMD_PP_TASK_COMPLETE_INIT);
575         mutex_unlock(&smu->mutex);
576
577         return 0;
578 }
579
580 int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
581                             uint16_t *size, uint8_t *frev, uint8_t *crev,
582                             uint8_t **addr)
583 {
584         struct amdgpu_device *adev = smu->adev;
585         uint16_t data_start;
586
587         if (!amdgpu_atom_parse_data_header(adev->mode_info.atom_context, table,
588                                            size, frev, crev, &data_start))
589                 return -EINVAL;
590
591         *addr = (uint8_t *)adev->mode_info.atom_context->bios + data_start;
592
593         return 0;
594 }
595
596 static int smu_initialize_pptable(struct smu_context *smu)
597 {
598         /* TODO */
599         return 0;
600 }
601
602 static int smu_smc_table_sw_init(struct smu_context *smu)
603 {
604         int ret;
605
606         ret = smu_initialize_pptable(smu);
607         if (ret) {
608                 pr_err("Failed to init smu_initialize_pptable!\n");
609                 return ret;
610         }
611
612         /**
613          * Create smu_table structure, and init smc tables such as
614          * TABLE_PPTABLE, TABLE_WATERMARKS, TABLE_SMU_METRICS, and etc.
615          */
616         ret = smu_init_smc_tables(smu);
617         if (ret) {
618                 pr_err("Failed to init smc tables!\n");
619                 return ret;
620         }
621
622         /**
623          * Create smu_power_context structure, and allocate smu_dpm_context and
624          * context size to fill the smu_power_context data.
625          */
626         ret = smu_init_power(smu);
627         if (ret) {
628                 pr_err("Failed to init smu_init_power!\n");
629                 return ret;
630         }
631
632         return 0;
633 }
634
635 static int smu_smc_table_sw_fini(struct smu_context *smu)
636 {
637         int ret;
638
639         ret = smu_fini_smc_tables(smu);
640         if (ret) {
641                 pr_err("Failed to smu_fini_smc_tables!\n");
642                 return ret;
643         }
644
645         return 0;
646 }
647
648 static int smu_sw_init(void *handle)
649 {
650         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
651         struct smu_context *smu = &adev->smu;
652         int ret;
653
654         smu->pool_size = adev->pm.smu_prv_buffer_size;
655         smu->smu_feature.feature_num = SMU_FEATURE_MAX;
656         mutex_init(&smu->smu_feature.mutex);
657         bitmap_zero(smu->smu_feature.supported, SMU_FEATURE_MAX);
658         bitmap_zero(smu->smu_feature.enabled, SMU_FEATURE_MAX);
659         bitmap_zero(smu->smu_feature.allowed, SMU_FEATURE_MAX);
660
661         mutex_init(&smu->smu_baco.mutex);
662         smu->smu_baco.state = SMU_BACO_STATE_EXIT;
663         smu->smu_baco.platform_support = false;
664
665         smu->watermarks_bitmap = 0;
666         smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
667         smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
668
669         smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
670         smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
671         smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
672         smu->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
673         smu->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 3;
674         smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4;
675         smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
676         smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
677
678         smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
679         smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
680         smu->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;
681         smu->workload_setting[3] = PP_SMC_POWER_PROFILE_VIDEO;
682         smu->workload_setting[4] = PP_SMC_POWER_PROFILE_VR;
683         smu->workload_setting[5] = PP_SMC_POWER_PROFILE_COMPUTE;
684         smu->workload_setting[6] = PP_SMC_POWER_PROFILE_CUSTOM;
685         smu->display_config = &adev->pm.pm_display_cfg;
686
687         smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
688         smu->smu_dpm.requested_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
689         ret = smu_init_microcode(smu);
690         if (ret) {
691                 pr_err("Failed to load smu firmware!\n");
692                 return ret;
693         }
694
695         ret = smu_smc_table_sw_init(smu);
696         if (ret) {
697                 pr_err("Failed to sw init smc table!\n");
698                 return ret;
699         }
700
701         return 0;
702 }
703
704 static int smu_sw_fini(void *handle)
705 {
706         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
707         struct smu_context *smu = &adev->smu;
708         int ret;
709
710         ret = smu_smc_table_sw_fini(smu);
711         if (ret) {
712                 pr_err("Failed to sw fini smc table!\n");
713                 return ret;
714         }
715
716         ret = smu_fini_power(smu);
717         if (ret) {
718                 pr_err("Failed to init smu_fini_power!\n");
719                 return ret;
720         }
721
722         return 0;
723 }
724
725 static int smu_init_fb_allocations(struct smu_context *smu)
726 {
727         struct amdgpu_device *adev = smu->adev;
728         struct smu_table_context *smu_table = &smu->smu_table;
729         struct smu_table *tables = smu_table->tables;
730         uint32_t table_count = smu_table->table_count;
731         uint32_t i = 0;
732         int32_t ret = 0;
733
734         if (table_count <= 0)
735                 return -EINVAL;
736
737         for (i = 0 ; i < table_count; i++) {
738                 if (tables[i].size == 0)
739                         continue;
740                 ret = amdgpu_bo_create_kernel(adev,
741                                               tables[i].size,
742                                               tables[i].align,
743                                               tables[i].domain,
744                                               &tables[i].bo,
745                                               &tables[i].mc_address,
746                                               &tables[i].cpu_addr);
747                 if (ret)
748                         goto failed;
749         }
750
751         return 0;
752 failed:
753         for (; i > 0; i--) {
754                 if (tables[i].size == 0)
755                         continue;
756                 amdgpu_bo_free_kernel(&tables[i].bo,
757                                       &tables[i].mc_address,
758                                       &tables[i].cpu_addr);
759
760         }
761         return ret;
762 }
763
764 static int smu_fini_fb_allocations(struct smu_context *smu)
765 {
766         struct smu_table_context *smu_table = &smu->smu_table;
767         struct smu_table *tables = smu_table->tables;
768         uint32_t table_count = smu_table->table_count;
769         uint32_t i = 0;
770
771         if (table_count == 0 || tables == NULL)
772                 return 0;
773
774         for (i = 0 ; i < table_count; i++) {
775                 if (tables[i].size == 0)
776                         continue;
777                 amdgpu_bo_free_kernel(&tables[i].bo,
778                                       &tables[i].mc_address,
779                                       &tables[i].cpu_addr);
780         }
781
782         return 0;
783 }
784
785 static int smu_override_pcie_parameters(struct smu_context *smu)
786 {
787         struct amdgpu_device *adev = smu->adev;
788         uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;
789         int ret;
790
791         if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
792                 pcie_gen = 3;
793         else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
794                 pcie_gen = 2;
795         else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
796                 pcie_gen = 1;
797         else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)
798                 pcie_gen = 0;
799
800         /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1
801          * Bit 15:8:  PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
802          * Bit 7:0:   PCIE lane width, 1 to 7 corresponds is x1 to x32
803          */
804         if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
805                 pcie_width = 6;
806         else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
807                 pcie_width = 5;
808         else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
809                 pcie_width = 4;
810         else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
811                 pcie_width = 3;
812         else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
813                 pcie_width = 2;
814         else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
815                 pcie_width = 1;
816
817         smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width;
818         ret = smu_send_smc_msg_with_param(smu,
819                                           SMU_MSG_OverridePcieParameters,
820                                           smu_pcie_arg);
821         if (ret)
822                 pr_err("[%s] Attempt to override pcie params failed!\n", __func__);
823         return ret;
824 }
825
826 static int smu_smc_table_hw_init(struct smu_context *smu,
827                                  bool initialize)
828 {
829         struct amdgpu_device *adev = smu->adev;
830         int ret;
831
832         if (smu_is_dpm_running(smu) && adev->in_suspend) {
833                 pr_info("dpm has been enabled\n");
834                 return 0;
835         }
836
837         ret = smu_init_display_count(smu, 0);
838         if (ret)
839                 return ret;
840
841         if (initialize) {
842                 /* get boot_values from vbios to set revision, gfxclk, and etc. */
843                 ret = smu_get_vbios_bootup_values(smu);
844                 if (ret)
845                         return ret;
846
847                 ret = smu_setup_pptable(smu);
848                 if (ret)
849                         return ret;
850
851                 ret = smu_get_clk_info_from_vbios(smu);
852                 if (ret)
853                         return ret;
854
855                 /*
856                  * check if the format_revision in vbios is up to pptable header
857                  * version, and the structure size is not 0.
858                  */
859                 ret = smu_check_pptable(smu);
860                 if (ret)
861                         return ret;
862
863                 /*
864                  * allocate vram bos to store smc table contents.
865                  */
866                 ret = smu_init_fb_allocations(smu);
867                 if (ret)
868                         return ret;
869
870                 /*
871                  * Parse pptable format and fill PPTable_t smc_pptable to
872                  * smu_table_context structure. And read the smc_dpm_table from vbios,
873                  * then fill it into smc_pptable.
874                  */
875                 ret = smu_parse_pptable(smu);
876                 if (ret)
877                         return ret;
878
879                 /*
880                  * Send msg GetDriverIfVersion to check if the return value is equal
881                  * with DRIVER_IF_VERSION of smc header.
882                  */
883                 ret = smu_check_fw_version(smu);
884                 if (ret)
885                         return ret;
886         }
887
888         /*
889          * Copy pptable bo in the vram to smc with SMU MSGs such as
890          * SetDriverDramAddr and TransferTableDram2Smu.
891          */
892         ret = smu_write_pptable(smu);
893         if (ret)
894                 return ret;
895
896         /* issue RunAfllBtc msg */
897         ret = smu_run_afll_btc(smu);
898         if (ret)
899                 return ret;
900
901         ret = smu_feature_set_allowed_mask(smu);
902         if (ret)
903                 return ret;
904
905         ret = smu_system_features_control(smu, true);
906         if (ret)
907                 return ret;
908
909         ret = smu_override_pcie_parameters(smu);
910         if (ret)
911                 return ret;
912
913         ret = smu_notify_display_change(smu);
914         if (ret)
915                 return ret;
916
917         /*
918          * Set min deep sleep dce fclk with bootup value from vbios via
919          * SetMinDeepSleepDcefclk MSG.
920          */
921         ret = smu_set_min_dcef_deep_sleep(smu);
922         if (ret)
923                 return ret;
924
925         /*
926          * Set initialized values (get from vbios) to dpm tables context such as
927          * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each
928          * type of clks.
929          */
930         if (initialize) {
931                 ret = smu_populate_smc_pptable(smu);
932                 if (ret)
933                         return ret;
934
935                 ret = smu_init_max_sustainable_clocks(smu);
936                 if (ret)
937                         return ret;
938         }
939
940         ret = smu_set_default_od_settings(smu, initialize);
941         if (ret)
942                 return ret;
943
944         if (initialize) {
945                 ret = smu_populate_umd_state_clk(smu);
946                 if (ret)
947                         return ret;
948
949                 ret = smu_get_power_limit(smu, &smu->default_power_limit, false);
950                 if (ret)
951                         return ret;
952         }
953
954         /*
955          * Set PMSTATUSLOG table bo address with SetToolsDramAddr MSG for tools.
956          */
957         ret = smu_set_tool_table_location(smu);
958
959         if (!smu_is_dpm_running(smu))
960                 pr_info("dpm has been disabled\n");
961
962         return ret;
963 }
964
965 /**
966  * smu_alloc_memory_pool - allocate memory pool in the system memory
967  *
968  * @smu: amdgpu_device pointer
969  *
970  * This memory pool will be used for SMC use and msg SetSystemVirtualDramAddr
971  * and DramLogSetDramAddr can notify it changed.
972  *
973  * Returns 0 on success, error on failure.
974  */
975 static int smu_alloc_memory_pool(struct smu_context *smu)
976 {
977         struct amdgpu_device *adev = smu->adev;
978         struct smu_table_context *smu_table = &smu->smu_table;
979         struct smu_table *memory_pool = &smu_table->memory_pool;
980         uint64_t pool_size = smu->pool_size;
981         int ret = 0;
982
983         if (pool_size == SMU_MEMORY_POOL_SIZE_ZERO)
984                 return ret;
985
986         memory_pool->size = pool_size;
987         memory_pool->align = PAGE_SIZE;
988         memory_pool->domain = AMDGPU_GEM_DOMAIN_GTT;
989
990         switch (pool_size) {
991         case SMU_MEMORY_POOL_SIZE_256_MB:
992         case SMU_MEMORY_POOL_SIZE_512_MB:
993         case SMU_MEMORY_POOL_SIZE_1_GB:
994         case SMU_MEMORY_POOL_SIZE_2_GB:
995                 ret = amdgpu_bo_create_kernel(adev,
996                                               memory_pool->size,
997                                               memory_pool->align,
998                                               memory_pool->domain,
999                                               &memory_pool->bo,
1000                                               &memory_pool->mc_address,
1001                                               &memory_pool->cpu_addr);
1002                 break;
1003         default:
1004                 break;
1005         }
1006
1007         return ret;
1008 }
1009
1010 static int smu_free_memory_pool(struct smu_context *smu)
1011 {
1012         struct smu_table_context *smu_table = &smu->smu_table;
1013         struct smu_table *memory_pool = &smu_table->memory_pool;
1014         int ret = 0;
1015
1016         if (memory_pool->size == SMU_MEMORY_POOL_SIZE_ZERO)
1017                 return ret;
1018
1019         amdgpu_bo_free_kernel(&memory_pool->bo,
1020                               &memory_pool->mc_address,
1021                               &memory_pool->cpu_addr);
1022
1023         memset(memory_pool, 0, sizeof(struct smu_table));
1024
1025         return ret;
1026 }
1027
1028 static int smu_hw_init(void *handle)
1029 {
1030         int ret;
1031         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1032         struct smu_context *smu = &adev->smu;
1033
1034         if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
1035                 ret = smu_check_fw_status(smu);
1036                 if (ret) {
1037                         pr_err("SMC firmware status is not correct\n");
1038                         return ret;
1039                 }
1040         }
1041
1042         ret = smu_feature_init_dpm(smu);
1043         if (ret)
1044                 goto failed;
1045
1046         ret = smu_smc_table_hw_init(smu, true);
1047         if (ret)
1048                 goto failed;
1049
1050         ret = smu_alloc_memory_pool(smu);
1051         if (ret)
1052                 goto failed;
1053
1054         /*
1055          * Use msg SetSystemVirtualDramAddr and DramLogSetDramAddr can notify
1056          * pool location.
1057          */
1058         ret = smu_notify_memory_pool_location(smu);
1059         if (ret)
1060                 goto failed;
1061
1062         ret = smu_start_thermal_control(smu);
1063         if (ret)
1064                 goto failed;
1065
1066         ret = smu_register_irq_handler(smu);
1067         if (ret)
1068                 goto failed;
1069
1070         if (!smu->pm_enabled)
1071                 adev->pm.dpm_enabled = false;
1072         else
1073                 adev->pm.dpm_enabled = true;    /* TODO: will set dpm_enabled flag while VCN and DAL DPM is workable */
1074
1075         pr_info("SMU is initialized successfully!\n");
1076
1077         return 0;
1078
1079 failed:
1080         return ret;
1081 }
1082
1083 static int smu_hw_fini(void *handle)
1084 {
1085         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1086         struct smu_context *smu = &adev->smu;
1087         struct smu_table_context *table_context = &smu->smu_table;
1088         int ret = 0;
1089
1090         kfree(table_context->driver_pptable);
1091         table_context->driver_pptable = NULL;
1092
1093         kfree(table_context->max_sustainable_clocks);
1094         table_context->max_sustainable_clocks = NULL;
1095
1096         kfree(table_context->overdrive_table);
1097         table_context->overdrive_table = NULL;
1098
1099         kfree(smu->irq_source);
1100         smu->irq_source = NULL;
1101
1102         ret = smu_fini_fb_allocations(smu);
1103         if (ret)
1104                 return ret;
1105
1106         ret = smu_free_memory_pool(smu);
1107         if (ret)
1108                 return ret;
1109
1110         return 0;
1111 }
1112
1113 int smu_reset(struct smu_context *smu)
1114 {
1115         struct amdgpu_device *adev = smu->adev;
1116         int ret = 0;
1117
1118         ret = smu_hw_fini(adev);
1119         if (ret)
1120                 return ret;
1121
1122         ret = smu_hw_init(adev);
1123         if (ret)
1124                 return ret;
1125
1126         return ret;
1127 }
1128
1129 static int smu_suspend(void *handle)
1130 {
1131         int ret;
1132         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1133         struct smu_context *smu = &adev->smu;
1134         bool baco_feature_is_enabled = smu_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT);
1135
1136         ret = smu_system_features_control(smu, false);
1137         if (ret)
1138                 return ret;
1139
1140         if (adev->in_gpu_reset && baco_feature_is_enabled) {
1141                 ret = smu_feature_set_enabled(smu, SMU_FEATURE_BACO_BIT, true);
1142                 if (ret) {
1143                         pr_warn("set BACO feature enabled failed, return %d\n", ret);
1144                         return ret;
1145                 }
1146         }
1147
1148         smu->watermarks_bitmap &= ~(WATERMARKS_LOADED);
1149
1150         if (adev->asic_type >= CHIP_NAVI10 &&
1151             adev->gfx.rlc.funcs->stop)
1152                 adev->gfx.rlc.funcs->stop(adev);
1153
1154         return 0;
1155 }
1156
1157 static int smu_resume(void *handle)
1158 {
1159         int ret;
1160         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1161         struct smu_context *smu = &adev->smu;
1162
1163         pr_info("SMU is resuming...\n");
1164
1165         mutex_lock(&smu->mutex);
1166
1167         ret = smu_smc_table_hw_init(smu, false);
1168         if (ret)
1169                 goto failed;
1170
1171         ret = smu_start_thermal_control(smu);
1172         if (ret)
1173                 goto failed;
1174
1175         mutex_unlock(&smu->mutex);
1176
1177         pr_info("SMU is resumed successfully!\n");
1178
1179         return 0;
1180 failed:
1181         mutex_unlock(&smu->mutex);
1182         return ret;
1183 }
1184
1185 int smu_display_configuration_change(struct smu_context *smu,
1186                                      const struct amd_pp_display_configuration *display_config)
1187 {
1188         int index = 0;
1189         int num_of_active_display = 0;
1190
1191         if (!smu->pm_enabled || !is_support_sw_smu(smu->adev))
1192                 return -EINVAL;
1193
1194         if (!display_config)
1195                 return -EINVAL;
1196
1197         mutex_lock(&smu->mutex);
1198
1199         smu_set_deep_sleep_dcefclk(smu,
1200                                    display_config->min_dcef_deep_sleep_set_clk / 100);
1201
1202         for (index = 0; index < display_config->num_path_including_non_display; index++) {
1203                 if (display_config->displays[index].controller_id != 0)
1204                         num_of_active_display++;
1205         }
1206
1207         smu_set_active_display_count(smu, num_of_active_display);
1208
1209         smu_store_cc6_data(smu, display_config->cpu_pstate_separation_time,
1210                            display_config->cpu_cc6_disable,
1211                            display_config->cpu_pstate_disable,
1212                            display_config->nb_pstate_switch_disable);
1213
1214         mutex_unlock(&smu->mutex);
1215
1216         return 0;
1217 }
1218
1219 static int smu_get_clock_info(struct smu_context *smu,
1220                               struct smu_clock_info *clk_info,
1221                               enum smu_perf_level_designation designation)
1222 {
1223         int ret;
1224         struct smu_performance_level level = {0};
1225
1226         if (!clk_info)
1227                 return -EINVAL;
1228
1229         ret = smu_get_perf_level(smu, PERF_LEVEL_ACTIVITY, &level);
1230         if (ret)
1231                 return -EINVAL;
1232
1233         clk_info->min_mem_clk = level.memory_clock;
1234         clk_info->min_eng_clk = level.core_clock;
1235         clk_info->min_bus_bandwidth = level.non_local_mem_freq * level.non_local_mem_width;
1236
1237         ret = smu_get_perf_level(smu, designation, &level);
1238         if (ret)
1239                 return -EINVAL;
1240
1241         clk_info->min_mem_clk = level.memory_clock;
1242         clk_info->min_eng_clk = level.core_clock;
1243         clk_info->min_bus_bandwidth = level.non_local_mem_freq * level.non_local_mem_width;
1244
1245         return 0;
1246 }
1247
1248 int smu_get_current_clocks(struct smu_context *smu,
1249                            struct amd_pp_clock_info *clocks)
1250 {
1251         struct amd_pp_simple_clock_info simple_clocks = {0};
1252         struct smu_clock_info hw_clocks;
1253         int ret = 0;
1254
1255         if (!is_support_sw_smu(smu->adev))
1256                 return -EINVAL;
1257
1258         mutex_lock(&smu->mutex);
1259
1260         smu_get_dal_power_level(smu, &simple_clocks);
1261
1262         if (smu->support_power_containment)
1263                 ret = smu_get_clock_info(smu, &hw_clocks,
1264                                          PERF_LEVEL_POWER_CONTAINMENT);
1265         else
1266                 ret = smu_get_clock_info(smu, &hw_clocks, PERF_LEVEL_ACTIVITY);
1267
1268         if (ret) {
1269                 pr_err("Error in smu_get_clock_info\n");
1270                 goto failed;
1271         }
1272
1273         clocks->min_engine_clock = hw_clocks.min_eng_clk;
1274         clocks->max_engine_clock = hw_clocks.max_eng_clk;
1275         clocks->min_memory_clock = hw_clocks.min_mem_clk;
1276         clocks->max_memory_clock = hw_clocks.max_mem_clk;
1277         clocks->min_bus_bandwidth = hw_clocks.min_bus_bandwidth;
1278         clocks->max_bus_bandwidth = hw_clocks.max_bus_bandwidth;
1279         clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1280         clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1281
1282         if (simple_clocks.level == 0)
1283                 clocks->max_clocks_state = PP_DAL_POWERLEVEL_7;
1284         else
1285                 clocks->max_clocks_state = simple_clocks.level;
1286
1287         if (!smu_get_current_shallow_sleep_clocks(smu, &hw_clocks)) {
1288                 clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1289                 clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1290         }
1291
1292 failed:
1293         mutex_unlock(&smu->mutex);
1294         return ret;
1295 }
1296
1297 static int smu_set_clockgating_state(void *handle,
1298                                      enum amd_clockgating_state state)
1299 {
1300         return 0;
1301 }
1302
1303 static int smu_set_powergating_state(void *handle,
1304                                      enum amd_powergating_state state)
1305 {
1306         return 0;
1307 }
1308
1309 static int smu_enable_umd_pstate(void *handle,
1310                       enum amd_dpm_forced_level *level)
1311 {
1312         uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
1313                                         AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
1314                                         AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
1315                                         AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
1316
1317         struct smu_context *smu = (struct smu_context*)(handle);
1318         struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
1319         if (!smu->pm_enabled || !smu_dpm_ctx->dpm_context)
1320                 return -EINVAL;
1321
1322         if (!(smu_dpm_ctx->dpm_level & profile_mode_mask)) {
1323                 /* enter umd pstate, save current level, disable gfx cg*/
1324                 if (*level & profile_mode_mask) {
1325                         smu_dpm_ctx->saved_dpm_level = smu_dpm_ctx->dpm_level;
1326                         smu_dpm_ctx->enable_umd_pstate = true;
1327                         amdgpu_device_ip_set_clockgating_state(smu->adev,
1328                                                                AMD_IP_BLOCK_TYPE_GFX,
1329                                                                AMD_CG_STATE_UNGATE);
1330                         amdgpu_device_ip_set_powergating_state(smu->adev,
1331                                                                AMD_IP_BLOCK_TYPE_GFX,
1332                                                                AMD_PG_STATE_UNGATE);
1333                 }
1334         } else {
1335                 /* exit umd pstate, restore level, enable gfx cg*/
1336                 if (!(*level & profile_mode_mask)) {
1337                         if (*level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)
1338                                 *level = smu_dpm_ctx->saved_dpm_level;
1339                         smu_dpm_ctx->enable_umd_pstate = false;
1340                         amdgpu_device_ip_set_clockgating_state(smu->adev,
1341                                                                AMD_IP_BLOCK_TYPE_GFX,
1342                                                                AMD_CG_STATE_GATE);
1343                         amdgpu_device_ip_set_powergating_state(smu->adev,
1344                                                                AMD_IP_BLOCK_TYPE_GFX,
1345                                                                AMD_PG_STATE_GATE);
1346                 }
1347         }
1348
1349         return 0;
1350 }
1351
1352 int smu_adjust_power_state_dynamic(struct smu_context *smu,
1353                                    enum amd_dpm_forced_level level,
1354                                    bool skip_display_settings)
1355 {
1356         int ret = 0;
1357         int index = 0;
1358         uint32_t sclk_mask, mclk_mask, soc_mask;
1359         long workload;
1360         struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
1361
1362         if (!smu->pm_enabled)
1363                 return -EINVAL;
1364         if (!skip_display_settings) {
1365                 ret = smu_display_config_changed(smu);
1366                 if (ret) {
1367                         pr_err("Failed to change display config!");
1368                         return ret;
1369                 }
1370         }
1371
1372         if (!smu->pm_enabled)
1373                 return -EINVAL;
1374         ret = smu_apply_clocks_adjust_rules(smu);
1375         if (ret) {
1376                 pr_err("Failed to apply clocks adjust rules!");
1377                 return ret;
1378         }
1379
1380         if (!skip_display_settings) {
1381                 ret = smu_notify_smc_dispaly_config(smu);
1382                 if (ret) {
1383                         pr_err("Failed to notify smc display config!");
1384                         return ret;
1385                 }
1386         }
1387
1388         if (smu_dpm_ctx->dpm_level != level) {
1389                 switch (level) {
1390                 case AMD_DPM_FORCED_LEVEL_HIGH:
1391                         ret = smu_force_dpm_limit_value(smu, true);
1392                         break;
1393                 case AMD_DPM_FORCED_LEVEL_LOW:
1394                         ret = smu_force_dpm_limit_value(smu, false);
1395                         break;
1396
1397                 case AMD_DPM_FORCED_LEVEL_AUTO:
1398                 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1399                         ret = smu_unforce_dpm_levels(smu);
1400                         break;
1401
1402                 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1403                 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1404                 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1405                         ret = smu_get_profiling_clk_mask(smu, level,
1406                                                          &sclk_mask,
1407                                                          &mclk_mask,
1408                                                          &soc_mask);
1409                         if (ret)
1410                                 return ret;
1411                         smu_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask);
1412                         smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask);
1413                         smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
1414                         break;
1415
1416                 case AMD_DPM_FORCED_LEVEL_MANUAL:
1417                 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
1418                 default:
1419                         break;
1420                 }
1421
1422                 if (!ret)
1423                         smu_dpm_ctx->dpm_level = level;
1424         }
1425
1426         if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
1427                 index = fls(smu->workload_mask);
1428                 index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
1429                 workload = smu->workload_setting[index];
1430
1431                 if (smu->power_profile_mode != workload)
1432                         smu_set_power_profile_mode(smu, &workload, 0);
1433         }
1434
1435         return ret;
1436 }
1437
1438 int smu_handle_task(struct smu_context *smu,
1439                     enum amd_dpm_forced_level level,
1440                     enum amd_pp_task task_id)
1441 {
1442         int ret = 0;
1443
1444         switch (task_id) {
1445         case AMD_PP_TASK_DISPLAY_CONFIG_CHANGE:
1446                 ret = smu_pre_display_config_changed(smu);
1447                 if (ret)
1448                         return ret;
1449                 ret = smu_set_cpu_power_state(smu);
1450                 if (ret)
1451                         return ret;
1452                 ret = smu_adjust_power_state_dynamic(smu, level, false);
1453                 break;
1454         case AMD_PP_TASK_COMPLETE_INIT:
1455         case AMD_PP_TASK_READJUST_POWER_STATE:
1456                 ret = smu_adjust_power_state_dynamic(smu, level, true);
1457                 break;
1458         default:
1459                 break;
1460         }
1461
1462         return ret;
1463 }
1464
1465 enum amd_dpm_forced_level smu_get_performance_level(struct smu_context *smu)
1466 {
1467         struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
1468         enum amd_dpm_forced_level level;
1469
1470         if (!smu_dpm_ctx->dpm_context)
1471                 return -EINVAL;
1472
1473         mutex_lock(&(smu->mutex));
1474         level = smu_dpm_ctx->dpm_level;
1475         mutex_unlock(&(smu->mutex));
1476
1477         return level;
1478 }
1479
1480 int smu_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
1481 {
1482         int ret = 0;
1483         int i;
1484         struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
1485
1486         if (!smu_dpm_ctx->dpm_context)
1487                 return -EINVAL;
1488
1489         for (i = 0; i < smu->adev->num_ip_blocks; i++) {
1490                 if (smu->adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC)
1491                         break;
1492         }
1493
1494
1495         smu->adev->ip_blocks[i].version->funcs->enable_umd_pstate(smu, &level);
1496         ret = smu_handle_task(smu, level,
1497                               AMD_PP_TASK_READJUST_POWER_STATE);
1498         if (ret)
1499                 return ret;
1500
1501         mutex_lock(&smu->mutex);
1502         smu_dpm_ctx->dpm_level = level;
1503         mutex_unlock(&smu->mutex);
1504
1505         return ret;
1506 }
1507
1508 int smu_set_display_count(struct smu_context *smu, uint32_t count)
1509 {
1510         int ret = 0;
1511
1512         mutex_lock(&smu->mutex);
1513         ret = smu_init_display_count(smu, count);
1514         mutex_unlock(&smu->mutex);
1515
1516         return ret;
1517 }
1518
1519 const struct amd_ip_funcs smu_ip_funcs = {
1520         .name = "smu",
1521         .early_init = smu_early_init,
1522         .late_init = smu_late_init,
1523         .sw_init = smu_sw_init,
1524         .sw_fini = smu_sw_fini,
1525         .hw_init = smu_hw_init,
1526         .hw_fini = smu_hw_fini,
1527         .suspend = smu_suspend,
1528         .resume = smu_resume,
1529         .is_idle = NULL,
1530         .check_soft_reset = NULL,
1531         .wait_for_idle = NULL,
1532         .soft_reset = NULL,
1533         .set_clockgating_state = smu_set_clockgating_state,
1534         .set_powergating_state = smu_set_powergating_state,
1535         .enable_umd_pstate = smu_enable_umd_pstate,
1536 };
1537
1538 const struct amdgpu_ip_block_version smu_v11_0_ip_block =
1539 {
1540         .type = AMD_IP_BLOCK_TYPE_SMC,
1541         .major = 11,
1542         .minor = 0,
1543         .rev = 0,
1544         .funcs = &smu_ip_funcs,
1545 };