2 * Copyright 2015 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
25 #include <linux/delay.h>
26 #include <linux/kernel.h>
27 #include <linux/slab.h>
28 #include <linux/types.h>
29 #include <drm/amdgpu_drm.h>
30 #include "cgs_common.h"
31 #include "power_state.h"
33 #include "pppcielanes.h"
34 #include "ppatomctrl.h"
39 extern int cz_init_function_pointers(struct pp_hwmgr *hwmgr);
41 static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr);
42 static void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr);
43 static int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr);
44 static int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr);
45 static int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr);
46 static int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr);
48 uint8_t convert_to_vid(uint16_t vddc)
50 return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25);
53 int hwmgr_early_init(struct pp_instance *handle)
55 struct pp_hwmgr *hwmgr;
60 hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL);
64 handle->hwmgr = hwmgr;
65 hwmgr->smumgr = handle->smu_mgr;
66 hwmgr->device = handle->device;
67 hwmgr->chip_family = handle->chip_family;
68 hwmgr->chip_id = handle->chip_id;
69 hwmgr->feature_mask = handle->feature_mask;
70 hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
71 hwmgr->power_source = PP_PowerSource_AC;
72 hwmgr->pp_table_version = PP_TABLE_V1;
73 hwmgr->dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
74 hwmgr_init_default_caps(hwmgr);
75 hwmgr_set_user_specify_caps(hwmgr);
77 switch (hwmgr->chip_family) {
78 case AMDGPU_FAMILY_CZ:
79 cz_init_function_pointers(hwmgr);
81 case AMDGPU_FAMILY_VI:
82 switch (hwmgr->chip_id) {
84 topaz_set_asic_special_caps(hwmgr);
85 hwmgr->feature_mask &= ~ (PP_VBI_TIME_SUPPORT_MASK |
86 PP_ENABLE_GFX_CG_THRU_SMU);
87 hwmgr->pp_table_version = PP_TABLE_V0;
90 tonga_set_asic_special_caps(hwmgr);
91 hwmgr->feature_mask &= ~PP_VBI_TIME_SUPPORT_MASK;
94 fiji_set_asic_special_caps(hwmgr);
95 hwmgr->feature_mask &= ~ (PP_VBI_TIME_SUPPORT_MASK |
96 PP_ENABLE_GFX_CG_THRU_SMU);
101 polaris_set_asic_special_caps(hwmgr);
102 hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
107 smu7_init_function_pointers(hwmgr);
109 case AMDGPU_FAMILY_AI:
110 switch (hwmgr->chip_id) {
112 vega10_hwmgr_init(hwmgr);
118 case AMDGPU_FAMILY_RV:
119 switch (hwmgr->chip_id) {
121 rv_init_function_pointers(hwmgr);
134 static int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
138 unsigned int table_entries;
139 struct pp_power_state *state;
142 if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
145 if (hwmgr->hwmgr_func->get_power_state_size == NULL)
148 hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr);
150 hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) +
151 sizeof(struct pp_power_state);
153 hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
154 if (hwmgr->ps == NULL)
157 hwmgr->request_ps = kzalloc(size, GFP_KERNEL);
158 if (hwmgr->request_ps == NULL) {
164 hwmgr->current_ps = kzalloc(size, GFP_KERNEL);
165 if (hwmgr->current_ps == NULL) {
166 kfree(hwmgr->request_ps);
168 hwmgr->request_ps = NULL;
175 for (i = 0; i < table_entries; i++) {
176 result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state);
178 if (state->classification.flags & PP_StateClassificationFlag_Boot) {
179 hwmgr->boot_ps = state;
180 memcpy(hwmgr->current_ps, state, size);
181 memcpy(hwmgr->request_ps, state, size);
184 state->id = i + 1; /* assigned unique num for every power state id */
186 if (state->classification.flags & PP_StateClassificationFlag_Uvd)
187 hwmgr->uvd_ps = state;
188 state = (struct pp_power_state *)((unsigned long)state + size);
194 static int hw_fini_power_state_table(struct pp_hwmgr *hwmgr)
199 kfree(hwmgr->current_ps);
200 kfree(hwmgr->request_ps);
202 hwmgr->request_ps = NULL;
204 hwmgr->current_ps = NULL;
208 int hwmgr_hw_init(struct pp_instance *handle)
210 struct pp_hwmgr *hwmgr;
216 hwmgr = handle->hwmgr;
218 if (hwmgr->pptable_func == NULL ||
219 hwmgr->pptable_func->pptable_init == NULL ||
220 hwmgr->hwmgr_func->backend_init == NULL)
223 ret = hwmgr->pptable_func->pptable_init(hwmgr);
227 ret = hwmgr->hwmgr_func->backend_init(hwmgr);
231 ret = hw_init_power_state_table(hwmgr);
236 if (hwmgr->hwmgr_func->backend_fini)
237 hwmgr->hwmgr_func->backend_fini(hwmgr);
239 if (hwmgr->pptable_func->pptable_fini)
240 hwmgr->pptable_func->pptable_fini(hwmgr);
242 pr_err("amdgpu: powerplay initialization failed\n");
246 int hwmgr_hw_fini(struct pp_instance *handle)
248 struct pp_hwmgr *hwmgr;
253 hwmgr = handle->hwmgr;
255 if (hwmgr->hwmgr_func->backend_fini)
256 hwmgr->hwmgr_func->backend_fini(hwmgr);
257 if (hwmgr->pptable_func->pptable_fini)
258 hwmgr->pptable_func->pptable_fini(hwmgr);
259 return hw_fini_power_state_table(hwmgr);
264 * Returns once the part of the register indicated by the mask has
265 * reached the given value.
267 int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
268 uint32_t value, uint32_t mask)
273 if (hwmgr == NULL || hwmgr->device == NULL) {
274 pr_err("Invalid Hardware Manager!");
278 for (i = 0; i < hwmgr->usec_timeout; i++) {
279 cur_value = cgs_read_register(hwmgr->device, index);
280 if ((cur_value & mask) == (value & mask))
285 /* timeout means wrong logic*/
286 if (i == hwmgr->usec_timeout)
293 * Returns once the part of the register indicated by the mask has
294 * reached the given value.The indirect space is described by giving
295 * the memory-mapped index of the indirect index register.
297 void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
298 uint32_t indirect_port,
303 if (hwmgr == NULL || hwmgr->device == NULL) {
304 pr_err("Invalid Hardware Manager!");
308 cgs_write_register(hwmgr->device, indirect_port, index);
309 phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);
314 bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr)
316 return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDPowerGating);
319 bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr)
321 return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEPowerGating);
325 int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table)
330 struct pp_atomctrl_voltage_table *table;
332 PP_ASSERT_WITH_CODE((NULL != vol_table),
333 "Voltage Table empty.", return -EINVAL);
335 table = kzalloc(sizeof(struct pp_atomctrl_voltage_table),
341 table->mask_low = vol_table->mask_low;
342 table->phase_delay = vol_table->phase_delay;
344 for (i = 0; i < vol_table->count; i++) {
345 vvalue = vol_table->entries[i].value;
348 for (j = 0; j < table->count; j++) {
349 if (vvalue == table->entries[j].value) {
356 table->entries[table->count].value = vvalue;
357 table->entries[table->count].smio_low =
358 vol_table->entries[i].smio_low;
363 memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table));
369 int phm_get_svi2_mvdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
370 phm_ppt_v1_clock_voltage_dependency_table *dep_table)
375 PP_ASSERT_WITH_CODE((0 != dep_table->count),
376 "Voltage Dependency Table empty.", return -EINVAL);
378 PP_ASSERT_WITH_CODE((NULL != vol_table),
379 "vol_table empty.", return -EINVAL);
381 vol_table->mask_low = 0;
382 vol_table->phase_delay = 0;
383 vol_table->count = dep_table->count;
385 for (i = 0; i < dep_table->count; i++) {
386 vol_table->entries[i].value = dep_table->entries[i].mvdd;
387 vol_table->entries[i].smio_low = 0;
390 result = phm_trim_voltage_table(vol_table);
391 PP_ASSERT_WITH_CODE((0 == result),
392 "Failed to trim MVDD table.", return result);
397 int phm_get_svi2_vddci_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
398 phm_ppt_v1_clock_voltage_dependency_table *dep_table)
403 PP_ASSERT_WITH_CODE((0 != dep_table->count),
404 "Voltage Dependency Table empty.", return -EINVAL);
406 PP_ASSERT_WITH_CODE((NULL != vol_table),
407 "vol_table empty.", return -EINVAL);
409 vol_table->mask_low = 0;
410 vol_table->phase_delay = 0;
411 vol_table->count = dep_table->count;
413 for (i = 0; i < dep_table->count; i++) {
414 vol_table->entries[i].value = dep_table->entries[i].vddci;
415 vol_table->entries[i].smio_low = 0;
418 result = phm_trim_voltage_table(vol_table);
419 PP_ASSERT_WITH_CODE((0 == result),
420 "Failed to trim VDDCI table.", return result);
425 int phm_get_svi2_vdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
426 phm_ppt_v1_voltage_lookup_table *lookup_table)
430 PP_ASSERT_WITH_CODE((0 != lookup_table->count),
431 "Voltage Lookup Table empty.", return -EINVAL);
433 PP_ASSERT_WITH_CODE((NULL != vol_table),
434 "vol_table empty.", return -EINVAL);
436 vol_table->mask_low = 0;
437 vol_table->phase_delay = 0;
439 vol_table->count = lookup_table->count;
441 for (i = 0; i < vol_table->count; i++) {
442 vol_table->entries[i].value = lookup_table->entries[i].us_vdd;
443 vol_table->entries[i].smio_low = 0;
449 void phm_trim_voltage_table_to_fit_state_table(uint32_t max_vol_steps,
450 struct pp_atomctrl_voltage_table *vol_table)
452 unsigned int i, diff;
454 if (vol_table->count <= max_vol_steps)
457 diff = vol_table->count - max_vol_steps;
459 for (i = 0; i < max_vol_steps; i++)
460 vol_table->entries[i] = vol_table->entries[i + diff];
462 vol_table->count = max_vol_steps;
467 int phm_reset_single_dpm_table(void *table,
468 uint32_t count, int max)
472 struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
474 dpm_table->count = count > max ? max : count;
476 for (i = 0; i < dpm_table->count; i++)
477 dpm_table->dpm_level[i].enabled = false;
482 void phm_setup_pcie_table_entry(
484 uint32_t index, uint32_t pcie_gen,
487 struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
488 dpm_table->dpm_level[index].value = pcie_gen;
489 dpm_table->dpm_level[index].param1 = pcie_lanes;
490 dpm_table->dpm_level[index].enabled = 1;
493 int32_t phm_get_dpm_level_enable_mask_value(void *table)
497 struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
499 for (i = dpm_table->count; i > 0; i--) {
501 if (dpm_table->dpm_level[i - 1].enabled)
510 uint8_t phm_get_voltage_index(
511 struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage)
513 uint8_t count = (uint8_t) (lookup_table->count);
516 PP_ASSERT_WITH_CODE((NULL != lookup_table),
517 "Lookup Table empty.", return 0);
518 PP_ASSERT_WITH_CODE((0 != count),
519 "Lookup Table empty.", return 0);
521 for (i = 0; i < lookup_table->count; i++) {
522 /* find first voltage equal or bigger than requested */
523 if (lookup_table->entries[i].us_vdd >= voltage)
526 /* voltage is bigger than max voltage in the table */
530 uint8_t phm_get_voltage_id(pp_atomctrl_voltage_table *voltage_table,
533 uint8_t count = (uint8_t) (voltage_table->count);
536 PP_ASSERT_WITH_CODE((NULL != voltage_table),
537 "Voltage Table empty.", return 0;);
538 PP_ASSERT_WITH_CODE((0 != count),
539 "Voltage Table empty.", return 0;);
541 for (i = 0; i < count; i++) {
542 /* find first voltage bigger than requested */
543 if (voltage_table->entries[i].value >= voltage)
547 /* voltage is bigger than max voltage in the table */
551 uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, uint16_t vddci)
555 for (i = 0; i < vddci_table->count; i++) {
556 if (vddci_table->entries[i].value >= vddci)
557 return vddci_table->entries[i].value;
560 pr_debug("vddci is larger than max value in vddci_table\n");
561 return vddci_table->entries[i-1].value;
564 int phm_find_boot_level(void *table,
565 uint32_t value, uint32_t *boot_level)
567 int result = -EINVAL;
569 struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
571 for (i = 0; i < dpm_table->count; i++) {
572 if (value == dpm_table->dpm_level[i].value) {
581 int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
582 phm_ppt_v1_voltage_lookup_table *lookup_table,
583 uint16_t virtual_voltage_id, int32_t *sclk)
587 struct phm_ppt_v1_information *table_info =
588 (struct phm_ppt_v1_information *)(hwmgr->pptable);
590 PP_ASSERT_WITH_CODE(lookup_table->count != 0, "Lookup table is empty", return -EINVAL);
592 /* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
593 for (entry_id = 0; entry_id < table_info->vdd_dep_on_sclk->count; entry_id++) {
594 voltage_id = table_info->vdd_dep_on_sclk->entries[entry_id].vddInd;
595 if (lookup_table->entries[voltage_id].us_vdd == virtual_voltage_id)
599 if (entry_id >= table_info->vdd_dep_on_sclk->count) {
600 pr_debug("Can't find requested voltage id in vdd_dep_on_sclk table\n");
604 *sclk = table_info->vdd_dep_on_sclk->entries[entry_id].clk;
610 * Initialize Dynamic State Adjustment Rule Settings
612 * @param hwmgr the address of the powerplay hardware manager.
614 int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr)
617 struct phm_clock_voltage_dependency_table *table_clk_vlt;
618 struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
620 /* initialize vddc_dep_on_dal_pwrl table */
621 table_size = sizeof(uint32_t) + 4 * sizeof(struct phm_clock_voltage_dependency_record);
622 table_clk_vlt = kzalloc(table_size, GFP_KERNEL);
624 if (NULL == table_clk_vlt) {
625 pr_err("Can not allocate space for vddc_dep_on_dal_pwrl! \n");
628 table_clk_vlt->count = 4;
629 table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_ULTRALOW;
630 table_clk_vlt->entries[0].v = 0;
631 table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_LOW;
632 table_clk_vlt->entries[1].v = 720;
633 table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_NOMINAL;
634 table_clk_vlt->entries[2].v = 810;
635 table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_PERFORMANCE;
636 table_clk_vlt->entries[3].v = 900;
637 if (pptable_info != NULL)
638 pptable_info->vddc_dep_on_dal_pwrl = table_clk_vlt;
639 hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
645 uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask)
649 while (0 == (mask & (1 << level)))
655 void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr)
657 struct phm_ppt_v1_information *table_info =
658 (struct phm_ppt_v1_information *)hwmgr->pptable;
659 struct phm_clock_voltage_dependency_table *table =
660 table_info->vddc_dep_on_dal_pwrl;
661 struct phm_ppt_v1_clock_voltage_dependency_table *vddc_table;
662 enum PP_DAL_POWERLEVEL dal_power_level = hwmgr->dal_power_level;
663 uint32_t req_vddc = 0, req_volt, i;
665 if (!table || table->count <= 0
666 || dal_power_level < PP_DAL_POWERLEVEL_ULTRALOW
667 || dal_power_level > PP_DAL_POWERLEVEL_PERFORMANCE)
670 for (i = 0; i < table->count; i++) {
671 if (dal_power_level == table->entries[i].clk) {
672 req_vddc = table->entries[i].v;
677 vddc_table = table_info->vdd_dep_on_sclk;
678 for (i = 0; i < vddc_table->count; i++) {
679 if (req_vddc <= vddc_table->entries[i].vddc) {
680 req_volt = (((uint32_t)vddc_table->entries[i].vddc) * VOLTAGE_SCALE);
681 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
682 PPSMC_MSG_VddC_Request, req_volt);
686 pr_err("DAL requested level can not"
687 " found a available voltage in VDDC DPM Table \n");
690 void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr)
692 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableVoltageTransition);
693 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableEngineTransition);
694 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMemoryTransition);
695 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGClockGating);
696 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGCGTSSM);
697 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLSClockGating);
698 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_Force3DClockSupport);
699 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLightSleep);
700 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMCLS);
701 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisablePowerGating);
703 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableDPM);
704 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableSMUUVDHandshake);
705 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ThermalAutoThrottling);
707 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
709 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_NoOD5Support);
710 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UserMaxClockForMultiDisplays);
712 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress);
714 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);
715 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);
717 if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) &&
718 acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION))
719 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
721 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
722 PHM_PlatformCaps_DynamicPatchPowerState);
724 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
725 PHM_PlatformCaps_EnableSMU7ThermalManagement);
727 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
728 PHM_PlatformCaps_DynamicPowerManagement);
730 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
731 PHM_PlatformCaps_SMC);
733 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
734 PHM_PlatformCaps_DynamicUVDState);
736 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
737 PHM_PlatformCaps_FanSpeedInTableIsRPM);
742 int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr)
744 if (hwmgr->feature_mask & PP_SCLK_DEEP_SLEEP_MASK)
745 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
746 PHM_PlatformCaps_SclkDeepSleep);
748 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
749 PHM_PlatformCaps_SclkDeepSleep);
751 if (hwmgr->feature_mask & PP_POWER_CONTAINMENT_MASK) {
752 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
753 PHM_PlatformCaps_PowerContainment);
754 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
755 PHM_PlatformCaps_CAC);
757 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
758 PHM_PlatformCaps_PowerContainment);
759 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
760 PHM_PlatformCaps_CAC);
766 int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
767 uint32_t sclk, uint16_t id, uint16_t *voltage)
772 if (hwmgr->chip_id < CHIP_TONGA) {
773 ret = atomctrl_get_voltage_evv(hwmgr, id, voltage);
774 } else if (hwmgr->chip_id < CHIP_POLARIS10) {
775 ret = atomctrl_get_voltage_evv_on_sclk(hwmgr, voltage_type, sclk, id, voltage);
776 if (*voltage >= 2000 || *voltage == 0)
779 ret = atomctrl_get_voltage_evv_on_sclk_ai(hwmgr, voltage_type, sclk, id, &vol);
780 *voltage = (uint16_t)(vol/100);
785 int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr)
788 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
789 PHM_PlatformCaps_SQRamping);
790 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
791 PHM_PlatformCaps_RegulatorHot);
793 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
794 PHM_PlatformCaps_AutomaticDCTransition);
796 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
797 PHM_PlatformCaps_TablelessHardwareInterface);
800 if (hwmgr->chip_id != CHIP_POLARIS10)
801 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
802 PHM_PlatformCaps_SPLLShutdownSupport);
804 if (hwmgr->chip_id != CHIP_POLARIS11) {
805 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
806 PHM_PlatformCaps_DBRamping);
807 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
808 PHM_PlatformCaps_TDRamping);
809 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
810 PHM_PlatformCaps_TCPRamping);
815 int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr)
817 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
818 PHM_PlatformCaps_SQRamping);
819 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
820 PHM_PlatformCaps_DBRamping);
821 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
822 PHM_PlatformCaps_TDRamping);
823 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
824 PHM_PlatformCaps_TCPRamping);
826 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
827 PHM_PlatformCaps_TablelessHardwareInterface);
832 int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr)
834 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
835 PHM_PlatformCaps_SQRamping);
836 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
837 PHM_PlatformCaps_DBRamping);
838 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
839 PHM_PlatformCaps_TDRamping);
840 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
841 PHM_PlatformCaps_TCPRamping);
843 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
844 PHM_PlatformCaps_UVDPowerGating);
845 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
846 PHM_PlatformCaps_VCEPowerGating);
848 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
849 PHM_PlatformCaps_TablelessHardwareInterface);
854 int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr)
856 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
857 PHM_PlatformCaps_SQRamping);
858 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
859 PHM_PlatformCaps_DBRamping);
860 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
861 PHM_PlatformCaps_TDRamping);
862 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
863 PHM_PlatformCaps_TCPRamping);
864 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
865 PHM_PlatformCaps_TablelessHardwareInterface);
866 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
867 PHM_PlatformCaps_EVV);