GNU Linux-libre 4.9.283-gnu1
[releases.git] / drivers / gpu / drm / amd / powerplay / hwmgr / hwmgr.c
1 /*
2  * Copyright 2015 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/delay.h"
24 #include <linux/types.h>
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
27 #include <drm/amdgpu_drm.h>
28 #include "cgs_common.h"
29 #include "power_state.h"
30 #include "hwmgr.h"
31 #include "pppcielanes.h"
32 #include "pp_debug.h"
33 #include "ppatomctrl.h"
34 #include "ppsmc.h"
35 #include "pp_acpi.h"
36 #include "amd_acpi.h"
37
38 extern int cz_hwmgr_init(struct pp_hwmgr *hwmgr);
39
40 static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr);
41 static void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr);
42 static int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr);
43 static int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr);
44 static int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr);
45 static int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr);
46
47 uint8_t convert_to_vid(uint16_t vddc)
48 {
49         return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25);
50 }
51
52 int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
53 {
54         struct pp_hwmgr *hwmgr;
55
56         if ((handle == NULL) || (pp_init == NULL))
57                 return -EINVAL;
58
59         hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL);
60         if (hwmgr == NULL)
61                 return -ENOMEM;
62
63         handle->hwmgr = hwmgr;
64         hwmgr->smumgr = handle->smu_mgr;
65         hwmgr->device = pp_init->device;
66         hwmgr->chip_family = pp_init->chip_family;
67         hwmgr->chip_id = pp_init->chip_id;
68         hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
69         hwmgr->power_source = PP_PowerSource_AC;
70         hwmgr->pp_table_version = PP_TABLE_V1;
71
72         hwmgr_init_default_caps(hwmgr);
73         hwmgr_set_user_specify_caps(hwmgr);
74
75         switch (hwmgr->chip_family) {
76         case AMDGPU_FAMILY_CZ:
77                 cz_hwmgr_init(hwmgr);
78                 break;
79         case AMDGPU_FAMILY_VI:
80                 switch (hwmgr->chip_id) {
81                 case CHIP_TOPAZ:
82                         topaz_set_asic_special_caps(hwmgr);
83                         hwmgr->feature_mask &= ~(PP_SMC_VOLTAGE_CONTROL_MASK |
84                                                 PP_VBI_TIME_SUPPORT_MASK |
85                                                 PP_ENABLE_GFX_CG_THRU_SMU);
86                         hwmgr->pp_table_version = PP_TABLE_V0;
87                         break;
88                 case CHIP_TONGA:
89                         tonga_set_asic_special_caps(hwmgr);
90                         hwmgr->feature_mask &= ~(PP_SMC_VOLTAGE_CONTROL_MASK |
91                                                 PP_VBI_TIME_SUPPORT_MASK);
92                         break;
93                 case CHIP_FIJI:
94                         fiji_set_asic_special_caps(hwmgr);
95                         hwmgr->feature_mask &= ~(PP_SMC_VOLTAGE_CONTROL_MASK |
96                                                 PP_VBI_TIME_SUPPORT_MASK |
97                                                 PP_ENABLE_GFX_CG_THRU_SMU);
98                         break;
99                 case CHIP_POLARIS11:
100                 case CHIP_POLARIS10:
101                         polaris_set_asic_special_caps(hwmgr);
102                         hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
103                         break;
104                 default:
105                         return -EINVAL;
106                 }
107                 smu7_hwmgr_init(hwmgr);
108                 break;
109         default:
110                 return -EINVAL;
111         }
112
113         return 0;
114 }
115
116 int hwmgr_fini(struct pp_hwmgr *hwmgr)
117 {
118         if (hwmgr == NULL || hwmgr->ps == NULL)
119                 return -EINVAL;
120
121         /* do hwmgr finish*/
122         kfree(hwmgr->hardcode_pp_table);
123
124         kfree(hwmgr->backend);
125
126         kfree(hwmgr->start_thermal_controller.function_list);
127
128         kfree(hwmgr->set_temperature_range.function_list);
129
130         kfree(hwmgr->ps);
131         kfree(hwmgr->current_ps);
132         kfree(hwmgr->request_ps);
133         kfree(hwmgr);
134         return 0;
135 }
136
137 int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
138 {
139         int result;
140         unsigned int i;
141         unsigned int table_entries;
142         struct pp_power_state *state;
143         int size;
144
145         if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
146                 return -EINVAL;
147
148         if (hwmgr->hwmgr_func->get_power_state_size == NULL)
149                 return -EINVAL;
150
151         hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr);
152
153         hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) +
154                                           sizeof(struct pp_power_state);
155
156         hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
157         if (hwmgr->ps == NULL)
158                 return -ENOMEM;
159
160         hwmgr->request_ps = kzalloc(size, GFP_KERNEL);
161         if (hwmgr->request_ps == NULL)
162                 return -ENOMEM;
163
164         hwmgr->current_ps = kzalloc(size, GFP_KERNEL);
165         if (hwmgr->current_ps == NULL)
166                 return -ENOMEM;
167
168         state = hwmgr->ps;
169
170         for (i = 0; i < table_entries; i++) {
171                 result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state);
172
173                 if (state->classification.flags & PP_StateClassificationFlag_Boot) {
174                         hwmgr->boot_ps = state;
175                         memcpy(hwmgr->current_ps, state, size);
176                         memcpy(hwmgr->request_ps, state, size);
177                 }
178
179                 state->id = i + 1; /* assigned unique num for every power state id */
180
181                 if (state->classification.flags & PP_StateClassificationFlag_Uvd)
182                         hwmgr->uvd_ps = state;
183                 state = (struct pp_power_state *)((unsigned long)state + size);
184         }
185
186
187         return 0;
188 }
189
190
191 /**
192  * Returns once the part of the register indicated by the mask has
193  * reached the given value.
194  */
195 int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
196                          uint32_t value, uint32_t mask)
197 {
198         uint32_t i;
199         uint32_t cur_value;
200
201         if (hwmgr == NULL || hwmgr->device == NULL) {
202                 printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
203                 return -EINVAL;
204         }
205
206         for (i = 0; i < hwmgr->usec_timeout; i++) {
207                 cur_value = cgs_read_register(hwmgr->device, index);
208                 if ((cur_value & mask) == (value & mask))
209                         break;
210                 udelay(1);
211         }
212
213         /* timeout means wrong logic*/
214         if (i == hwmgr->usec_timeout)
215                 return -1;
216         return 0;
217 }
218
219
220 /**
221  * Returns once the part of the register indicated by the mask has
222  * reached the given value.The indirect space is described by giving
223  * the memory-mapped index of the indirect index register.
224  */
225 void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
226                                 uint32_t indirect_port,
227                                 uint32_t index,
228                                 uint32_t value,
229                                 uint32_t mask)
230 {
231         if (hwmgr == NULL || hwmgr->device == NULL) {
232                 printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
233                 return;
234         }
235
236         cgs_write_register(hwmgr->device, indirect_port, index);
237         phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);
238 }
239
240
241
242 bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr)
243 {
244         return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDPowerGating);
245 }
246
247 bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr)
248 {
249         return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEPowerGating);
250 }
251
252
253 int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table)
254 {
255         uint32_t i, j;
256         uint16_t vvalue;
257         bool found = false;
258         struct pp_atomctrl_voltage_table *table;
259
260         PP_ASSERT_WITH_CODE((NULL != vol_table),
261                         "Voltage Table empty.", return -EINVAL);
262
263         table = kzalloc(sizeof(struct pp_atomctrl_voltage_table),
264                         GFP_KERNEL);
265
266         if (NULL == table)
267                 return -EINVAL;
268
269         table->mask_low = vol_table->mask_low;
270         table->phase_delay = vol_table->phase_delay;
271
272         for (i = 0; i < vol_table->count; i++) {
273                 vvalue = vol_table->entries[i].value;
274                 found = false;
275
276                 for (j = 0; j < table->count; j++) {
277                         if (vvalue == table->entries[j].value) {
278                                 found = true;
279                                 break;
280                         }
281                 }
282
283                 if (!found) {
284                         table->entries[table->count].value = vvalue;
285                         table->entries[table->count].smio_low =
286                                         vol_table->entries[i].smio_low;
287                         table->count++;
288                 }
289         }
290
291         memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table));
292         kfree(table);
293
294         return 0;
295 }
296
297 int phm_get_svi2_mvdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
298                 phm_ppt_v1_clock_voltage_dependency_table *dep_table)
299 {
300         uint32_t i;
301         int result;
302
303         PP_ASSERT_WITH_CODE((0 != dep_table->count),
304                         "Voltage Dependency Table empty.", return -EINVAL);
305
306         PP_ASSERT_WITH_CODE((NULL != vol_table),
307                         "vol_table empty.", return -EINVAL);
308
309         vol_table->mask_low = 0;
310         vol_table->phase_delay = 0;
311         vol_table->count = dep_table->count;
312
313         for (i = 0; i < dep_table->count; i++) {
314                 vol_table->entries[i].value = dep_table->entries[i].mvdd;
315                 vol_table->entries[i].smio_low = 0;
316         }
317
318         result = phm_trim_voltage_table(vol_table);
319         PP_ASSERT_WITH_CODE((0 == result),
320                         "Failed to trim MVDD table.", return result);
321
322         return 0;
323 }
324
325 int phm_get_svi2_vddci_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
326                 phm_ppt_v1_clock_voltage_dependency_table *dep_table)
327 {
328         uint32_t i;
329         int result;
330
331         PP_ASSERT_WITH_CODE((0 != dep_table->count),
332                         "Voltage Dependency Table empty.", return -EINVAL);
333
334         PP_ASSERT_WITH_CODE((NULL != vol_table),
335                         "vol_table empty.", return -EINVAL);
336
337         vol_table->mask_low = 0;
338         vol_table->phase_delay = 0;
339         vol_table->count = dep_table->count;
340
341         for (i = 0; i < dep_table->count; i++) {
342                 vol_table->entries[i].value = dep_table->entries[i].vddci;
343                 vol_table->entries[i].smio_low = 0;
344         }
345
346         result = phm_trim_voltage_table(vol_table);
347         PP_ASSERT_WITH_CODE((0 == result),
348                         "Failed to trim VDDCI table.", return result);
349
350         return 0;
351 }
352
353 int phm_get_svi2_vdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
354                 phm_ppt_v1_voltage_lookup_table *lookup_table)
355 {
356         int i = 0;
357
358         PP_ASSERT_WITH_CODE((0 != lookup_table->count),
359                         "Voltage Lookup Table empty.", return -EINVAL);
360
361         PP_ASSERT_WITH_CODE((NULL != vol_table),
362                         "vol_table empty.", return -EINVAL);
363
364         vol_table->mask_low = 0;
365         vol_table->phase_delay = 0;
366
367         vol_table->count = lookup_table->count;
368
369         for (i = 0; i < vol_table->count; i++) {
370                 vol_table->entries[i].value = lookup_table->entries[i].us_vdd;
371                 vol_table->entries[i].smio_low = 0;
372         }
373
374         return 0;
375 }
376
377 void phm_trim_voltage_table_to_fit_state_table(uint32_t max_vol_steps,
378                                 struct pp_atomctrl_voltage_table *vol_table)
379 {
380         unsigned int i, diff;
381
382         if (vol_table->count <= max_vol_steps)
383                 return;
384
385         diff = vol_table->count - max_vol_steps;
386
387         for (i = 0; i < max_vol_steps; i++)
388                 vol_table->entries[i] = vol_table->entries[i + diff];
389
390         vol_table->count = max_vol_steps;
391
392         return;
393 }
394
395 int phm_reset_single_dpm_table(void *table,
396                                 uint32_t count, int max)
397 {
398         int i;
399
400         struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
401
402         dpm_table->count = count > max ? max : count;
403
404         for (i = 0; i < dpm_table->count; i++)
405                 dpm_table->dpm_level[i].enabled = false;
406
407         return 0;
408 }
409
410 void phm_setup_pcie_table_entry(
411         void *table,
412         uint32_t index, uint32_t pcie_gen,
413         uint32_t pcie_lanes)
414 {
415         struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
416         dpm_table->dpm_level[index].value = pcie_gen;
417         dpm_table->dpm_level[index].param1 = pcie_lanes;
418         dpm_table->dpm_level[index].enabled = 1;
419 }
420
421 int32_t phm_get_dpm_level_enable_mask_value(void *table)
422 {
423         int32_t i;
424         int32_t mask = 0;
425         struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
426
427         for (i = dpm_table->count; i > 0; i--) {
428                 mask = mask << 1;
429                 if (dpm_table->dpm_level[i - 1].enabled)
430                         mask |= 0x1;
431                 else
432                         mask &= 0xFFFFFFFE;
433         }
434
435         return mask;
436 }
437
438 uint8_t phm_get_voltage_index(
439                 struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage)
440 {
441         uint8_t count = (uint8_t) (lookup_table->count);
442         uint8_t i;
443
444         PP_ASSERT_WITH_CODE((NULL != lookup_table),
445                         "Lookup Table empty.", return 0);
446         PP_ASSERT_WITH_CODE((0 != count),
447                         "Lookup Table empty.", return 0);
448
449         for (i = 0; i < lookup_table->count; i++) {
450                 /* find first voltage equal or bigger than requested */
451                 if (lookup_table->entries[i].us_vdd >= voltage)
452                         return i;
453         }
454         /* voltage is bigger than max voltage in the table */
455         return i - 1;
456 }
457
458 uint8_t phm_get_voltage_id(pp_atomctrl_voltage_table *voltage_table,
459                 uint32_t voltage)
460 {
461         uint8_t count = (uint8_t) (voltage_table->count);
462         uint8_t i = 0;
463
464         PP_ASSERT_WITH_CODE((NULL != voltage_table),
465                 "Voltage Table empty.", return 0;);
466         PP_ASSERT_WITH_CODE((0 != count),
467                 "Voltage Table empty.", return 0;);
468
469         for (i = 0; i < count; i++) {
470                 /* find first voltage bigger than requested */
471                 if (voltage_table->entries[i].value >= voltage)
472                         return i;
473         }
474
475         /* voltage is bigger than max voltage in the table */
476         return i - 1;
477 }
478
479 uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, uint16_t vddci)
480 {
481         uint32_t  i;
482
483         for (i = 0; i < vddci_table->count; i++) {
484                 if (vddci_table->entries[i].value >= vddci)
485                         return vddci_table->entries[i].value;
486         }
487
488         PP_ASSERT_WITH_CODE(false,
489                         "VDDCI is larger than max VDDCI in VDDCI Voltage Table!",
490                         return vddci_table->entries[i-1].value);
491 }
492
493 int phm_find_boot_level(void *table,
494                 uint32_t value, uint32_t *boot_level)
495 {
496         int result = -EINVAL;
497         uint32_t i;
498         struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
499
500         for (i = 0; i < dpm_table->count; i++) {
501                 if (value == dpm_table->dpm_level[i].value) {
502                         *boot_level = i;
503                         result = 0;
504                 }
505         }
506
507         return result;
508 }
509
510 int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
511         phm_ppt_v1_voltage_lookup_table *lookup_table,
512         uint16_t virtual_voltage_id, int32_t *sclk)
513 {
514         uint8_t entryId;
515         uint8_t voltageId;
516         struct phm_ppt_v1_information *table_info =
517                         (struct phm_ppt_v1_information *)(hwmgr->pptable);
518
519         PP_ASSERT_WITH_CODE(lookup_table->count != 0, "Lookup table is empty", return -EINVAL);
520
521         /* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
522         for (entryId = 0; entryId < table_info->vdd_dep_on_sclk->count; entryId++) {
523                 voltageId = table_info->vdd_dep_on_sclk->entries[entryId].vddInd;
524                 if (lookup_table->entries[voltageId].us_vdd == virtual_voltage_id)
525                         break;
526         }
527
528         PP_ASSERT_WITH_CODE(entryId < table_info->vdd_dep_on_sclk->count,
529                         "Can't find requested voltage id in vdd_dep_on_sclk table!",
530                         return -EINVAL;
531                         );
532
533         *sclk = table_info->vdd_dep_on_sclk->entries[entryId].clk;
534
535         return 0;
536 }
537
538 /**
539  * Initialize Dynamic State Adjustment Rule Settings
540  *
541  * @param    hwmgr  the address of the powerplay hardware manager.
542  */
543 int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr)
544 {
545         uint32_t table_size;
546         struct phm_clock_voltage_dependency_table *table_clk_vlt;
547         struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
548
549         /* initialize vddc_dep_on_dal_pwrl table */
550         table_size = sizeof(uint32_t) + 4 * sizeof(struct phm_clock_voltage_dependency_record);
551         table_clk_vlt = kzalloc(table_size, GFP_KERNEL);
552
553         if (NULL == table_clk_vlt) {
554                 printk(KERN_ERR "[ powerplay ] Can not allocate space for vddc_dep_on_dal_pwrl! \n");
555                 return -ENOMEM;
556         } else {
557                 table_clk_vlt->count = 4;
558                 table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_ULTRALOW;
559                 table_clk_vlt->entries[0].v = 0;
560                 table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_LOW;
561                 table_clk_vlt->entries[1].v = 720;
562                 table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_NOMINAL;
563                 table_clk_vlt->entries[2].v = 810;
564                 table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_PERFORMANCE;
565                 table_clk_vlt->entries[3].v = 900;
566                 if (pptable_info != NULL)
567                         pptable_info->vddc_dep_on_dal_pwrl = table_clk_vlt;
568                 hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
569         }
570
571         return 0;
572 }
573
574 int phm_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
575 {
576         if (NULL != hwmgr->dyn_state.vddc_dep_on_dal_pwrl) {
577                 kfree(hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
578                 hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
579         }
580
581         if (NULL != hwmgr->backend) {
582                 kfree(hwmgr->backend);
583                 hwmgr->backend = NULL;
584         }
585
586         return 0;
587 }
588
589 uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask)
590 {
591         uint32_t level = 0;
592
593         while (0 == (mask & (1 << level)))
594                 level++;
595
596         return level;
597 }
598
599 void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr)
600 {
601         struct phm_ppt_v1_information *table_info =
602                         (struct phm_ppt_v1_information *)hwmgr->pptable;
603         struct phm_clock_voltage_dependency_table *table =
604                                 table_info->vddc_dep_on_dal_pwrl;
605         struct phm_ppt_v1_clock_voltage_dependency_table *vddc_table;
606         enum PP_DAL_POWERLEVEL dal_power_level = hwmgr->dal_power_level;
607         uint32_t req_vddc = 0, req_volt, i;
608
609         if (!table || table->count <= 0
610                 || dal_power_level < PP_DAL_POWERLEVEL_ULTRALOW
611                 || dal_power_level > PP_DAL_POWERLEVEL_PERFORMANCE)
612                 return;
613
614         for (i = 0; i < table->count; i++) {
615                 if (dal_power_level == table->entries[i].clk) {
616                         req_vddc = table->entries[i].v;
617                         break;
618                 }
619         }
620
621         vddc_table = table_info->vdd_dep_on_sclk;
622         for (i = 0; i < vddc_table->count; i++) {
623                 if (req_vddc <= vddc_table->entries[i].vddc) {
624                         req_volt = (((uint32_t)vddc_table->entries[i].vddc) * VOLTAGE_SCALE);
625                         smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
626                                         PPSMC_MSG_VddC_Request, req_volt);
627                         return;
628                 }
629         }
630         printk(KERN_ERR "DAL requested level can not"
631                         " found a available voltage in VDDC DPM Table \n");
632 }
633
634 void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr)
635 {
636         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableVoltageTransition);
637         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableEngineTransition);
638         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMemoryTransition);
639         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGClockGating);
640         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGCGTSSM);
641         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLSClockGating);
642         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_Force3DClockSupport);
643         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLightSleep);
644         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMCLS);
645         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisablePowerGating);
646
647         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableDPM);
648         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableSMUUVDHandshake);
649         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ThermalAutoThrottling);
650
651         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
652
653         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_NoOD5Support);
654         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UserMaxClockForMultiDisplays);
655
656         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress);
657
658         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);
659         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);
660
661         if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) &&
662                 acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION))
663                 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
664
665         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
666                 PHM_PlatformCaps_DynamicPatchPowerState);
667
668         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
669                 PHM_PlatformCaps_EnableSMU7ThermalManagement);
670
671         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
672                         PHM_PlatformCaps_DynamicPowerManagement);
673
674         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
675                                         PHM_PlatformCaps_SMC);
676
677         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
678                                         PHM_PlatformCaps_DynamicUVDState);
679
680         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
681                                                 PHM_PlatformCaps_FanSpeedInTableIsRPM);
682
683         return;
684 }
685
686 int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr)
687 {
688         if (amdgpu_sclk_deep_sleep_en)
689                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
690                         PHM_PlatformCaps_SclkDeepSleep);
691         else
692                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
693                         PHM_PlatformCaps_SclkDeepSleep);
694
695         if (amdgpu_powercontainment)
696                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
697                             PHM_PlatformCaps_PowerContainment);
698         else
699                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
700                             PHM_PlatformCaps_PowerContainment);
701
702         hwmgr->feature_mask = amdgpu_pp_feature_mask;
703
704         return 0;
705 }
706
707 int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
708                                 uint32_t sclk, uint16_t id, uint16_t *voltage)
709 {
710         uint32_t vol;
711         int ret = 0;
712
713         if (hwmgr->chip_id < CHIP_TONGA) {
714                 ret = atomctrl_get_voltage_evv(hwmgr, id, voltage);
715         } else if (hwmgr->chip_id < CHIP_POLARIS10) {
716                 ret = atomctrl_get_voltage_evv_on_sclk(hwmgr, voltage_type, sclk, id, voltage);
717                 if (*voltage >= 2000 || *voltage == 0)
718                         *voltage = 1150;
719         } else {
720                 ret = atomctrl_get_voltage_evv_on_sclk_ai(hwmgr, voltage_type, sclk, id, &vol);
721                 *voltage = (uint16_t)(vol/100);
722         }
723         return ret;
724 }
725
726 int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr)
727 {
728         /* power tune caps Assume disabled */
729         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
730                                                 PHM_PlatformCaps_SQRamping);
731         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
732                                                 PHM_PlatformCaps_DBRamping);
733         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
734                                                 PHM_PlatformCaps_TDRamping);
735         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
736                                                 PHM_PlatformCaps_TCPRamping);
737
738         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
739                                                         PHM_PlatformCaps_CAC);
740
741         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
742                                                 PHM_PlatformCaps_RegulatorHot);
743
744         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
745                                         PHM_PlatformCaps_AutomaticDCTransition);
746
747         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
748                                 PHM_PlatformCaps_TablelessHardwareInterface);
749
750         if (hwmgr->chip_id == CHIP_POLARIS11)
751                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
752                                         PHM_PlatformCaps_SPLLShutdownSupport);
753         return 0;
754 }
755
756 int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr)
757 {
758         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
759                         PHM_PlatformCaps_SQRamping);
760         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
761                         PHM_PlatformCaps_DBRamping);
762         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
763                         PHM_PlatformCaps_TDRamping);
764         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
765                         PHM_PlatformCaps_TCPRamping);
766
767         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
768                         PHM_PlatformCaps_TablelessHardwareInterface);
769
770         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
771                         PHM_PlatformCaps_CAC);
772         return 0;
773 }
774
775 int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr)
776 {
777         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
778                         PHM_PlatformCaps_SQRamping);
779         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
780                         PHM_PlatformCaps_DBRamping);
781         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
782                         PHM_PlatformCaps_TDRamping);
783         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
784                         PHM_PlatformCaps_TCPRamping);
785
786         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
787                       PHM_PlatformCaps_UVDPowerGating);
788         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
789                       PHM_PlatformCaps_VCEPowerGating);
790
791         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
792                          PHM_PlatformCaps_TablelessHardwareInterface);
793
794         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
795                         PHM_PlatformCaps_CAC);
796
797         return 0;
798 }
799
800 int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr)
801 {
802         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
803                         PHM_PlatformCaps_SQRamping);
804         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
805                         PHM_PlatformCaps_DBRamping);
806         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
807                         PHM_PlatformCaps_TDRamping);
808         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
809                         PHM_PlatformCaps_TCPRamping);
810         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
811                          PHM_PlatformCaps_TablelessHardwareInterface);
812         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
813                         PHM_PlatformCaps_CAC);
814         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
815                     PHM_PlatformCaps_EVV);
816         return 0;
817 }