diff options
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/hwmgr')
17 files changed, 533 insertions, 276 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile index abbcbc9f6eca..6e359c90dfda 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile @@ -5,7 +5,7 @@ HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \ hardwaremanager.o pp_acpi.o cz_hwmgr.o \ cz_clockpowergating.o tonga_powertune.o\ - tonga_processpptables.o ppatomctrl.o \ + process_pptables_v1_0.o ppatomctrl.o \ tonga_hwmgr.o pppcielanes.o tonga_thermal.o\ fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o \ fiji_clockpowergating.o fiji_thermal.o \ diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 9368e21f5695..74300d6ef686 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c @@ -44,8 +44,8 @@ #include "dce/dce_10_0_sh_mask.h" #include "pppcielanes.h" #include "fiji_hwmgr.h" -#include "tonga_processpptables.h" -#include "tonga_pptable.h" +#include "process_pptables_v1_0.h" +#include "pptable_v1_0.h" #include "pp_debug.h" #include "pp_acpi.h" #include "amd_pcie_helpers.h" @@ -112,7 +112,7 @@ static const uint8_t fiji_clock_stretch_amount_conversion[2][6] = static const unsigned long PhwFiji_Magic = (unsigned long)(PHM_VIslands_Magic); -struct fiji_power_state *cast_phw_fiji_power_state( +static struct fiji_power_state *cast_phw_fiji_power_state( struct pp_hw_power_state *hw_ps) { PP_ASSERT_WITH_CODE((PhwFiji_Magic == hw_ps->magic), @@ -122,7 +122,8 @@ struct fiji_power_state *cast_phw_fiji_power_state( return (struct fiji_power_state *)hw_ps; } -const struct fiji_power_state *cast_const_phw_fiji_power_state( +static const struct +fiji_power_state *cast_const_phw_fiji_power_state( const struct pp_hw_power_state *hw_ps) { PP_ASSERT_WITH_CODE((PhwFiji_Magic == hw_ps->magic), @@ -1626,7 +1627,7 @@ static int fiji_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) * @param voltage - voltage to look for * @return 0 on success */ -uint8_t fiji_get_voltage_index( +static uint8_t fiji_get_voltage_index( struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage) { uint8_t count = (uint8_t) (lookup_table->count); @@ -1690,7 +1691,7 @@ static int fiji_populate_cac_table(struct pp_hwmgr *hwmgr, * @return always 0 */ -int fiji_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, +static int fiji_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, struct SMU73_Discrete_DpmTable *table) { int result; @@ -2301,7 +2302,7 @@ static int fiji_populate_all_memory_levels(struct pp_hwmgr *hwmgr) * @param mclk the MCLK value to be used in the decision if MVDD should be high or low. * @param voltage the SMC VOLTAGE structure to be populated */ -int fiji_populate_mvdd_value(struct pp_hwmgr *hwmgr, +static int fiji_populate_mvdd_value(struct pp_hwmgr *hwmgr, uint32_t mclk, SMIO_Pattern *smio_pat) { const struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); @@ -4005,7 +4006,7 @@ static int fiji_get_pp_table_entry(struct pp_hwmgr *hwmgr, ps = (struct fiji_power_state *)(&state->hardware); - result = tonga_get_powerplay_table_entry(hwmgr, entry_index, state, + result = get_powerplay_table_entry_v1_0(hwmgr, entry_index, state, fiji_get_pp_table_entry_callback_func); /* This is the earliest time we have all the dependency table and the VBIOS boot state @@ -4622,7 +4623,7 @@ static int fiji_generate_dpm_level_enable_mask( return 0; } -int fiji_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable) +static int fiji_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable) { return smum_send_msg_to_smc(hwmgr->smumgr, enable ? (PPSMC_Msg)PPSMC_MSG_UVDDPM_Enable : @@ -4636,14 +4637,14 @@ int fiji_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) PPSMC_MSG_VCEDPM_Disable); } -int fiji_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable) +static int fiji_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable) { return smum_send_msg_to_smc(hwmgr->smumgr, enable? PPSMC_MSG_SAMUDPM_Enable : PPSMC_MSG_SAMUDPM_Disable); } -int fiji_enable_disable_acp_dpm(struct pp_hwmgr *hwmgr, bool enable) +static int fiji_enable_disable_acp_dpm(struct pp_hwmgr *hwmgr, bool enable) { return smum_send_msg_to_smc(hwmgr->smumgr, enable? PPSMC_MSG_ACPDPM_Enable : @@ -4880,7 +4881,7 @@ static void fiji_apply_dal_minimum_voltage_request(struct pp_hwmgr *hwmgr) return; } -int fiji_upload_dpm_level_enable_mask(struct pp_hwmgr *hwmgr) +static int fiji_upload_dpm_level_enable_mask(struct pp_hwmgr *hwmgr) { int result; struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); @@ -5156,7 +5157,7 @@ static int fiji_program_display_gap(struct pp_hwmgr *hwmgr) return 0; } -int fiji_display_configuration_changed_task(struct pp_hwmgr *hwmgr) +static int fiji_display_configuration_changed_task(struct pp_hwmgr *hwmgr) { return fiji_program_display_gap(hwmgr); } @@ -5187,7 +5188,7 @@ static int fiji_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, PPSMC_MSG_SetFanRpmMax, us_max_fan_rpm); } -int fiji_dpm_set_interrupt_state(void *private_data, +static int fiji_dpm_set_interrupt_state(void *private_data, unsigned src_id, unsigned type, int enabled) { @@ -5235,7 +5236,7 @@ int fiji_dpm_set_interrupt_state(void *private_data, return 0; } -int fiji_register_internal_thermal_interrupt(struct pp_hwmgr *hwmgr, +static int fiji_register_internal_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *thermal_interrupt_info) { int result; @@ -5405,7 +5406,10 @@ static inline bool fiji_are_power_levels_equal(const struct fiji_performance_lev (pl1->pcie_lane == pl2->pcie_lane)); } -int fiji_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal) +static int +fiji_check_states_equal(struct pp_hwmgr *hwmgr, + const struct pp_hw_power_state *pstate1, + const struct pp_hw_power_state *pstate2, bool *equal) { const struct fiji_power_state *psa = cast_const_phw_fiji_power_state(pstate1); const struct fiji_power_state *psb = cast_const_phw_fiji_power_state(pstate2); @@ -5437,7 +5441,8 @@ int fiji_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_sta return 0; } -bool fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) +static bool +fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) { struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); bool is_update_required = false; @@ -5547,7 +5552,7 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = { .dynamic_state_management_enable = &fiji_enable_dpm_tasks, .dynamic_state_management_disable = &fiji_disable_dpm_tasks, .force_dpm_level = &fiji_dpm_force_dpm_level, - .get_num_of_pp_table_entries = &tonga_get_number_of_powerplay_table_entries, + .get_num_of_pp_table_entries = &get_number_of_powerplay_table_entries_v1_0, .get_power_state_size = &fiji_get_power_state_size, .get_pp_table_entry = &fiji_get_pp_table_entry, .patch_boot_state = &fiji_patch_boot_state, @@ -5589,7 +5594,7 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = { int fiji_hwmgr_init(struct pp_hwmgr *hwmgr) { hwmgr->hwmgr_func = &fiji_hwmgr_funcs; - hwmgr->pptable_func = &tonga_pptable_funcs; + hwmgr->pptable_func = &pptable_v1_0_funcs; pp_fiji_thermal_initialize(hwmgr); return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_thermal.c index 92976b68d6fd..7f431e762262 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_thermal.c @@ -152,7 +152,7 @@ int fiji_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr) return 0; } -int fiji_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr) +static int fiji_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr) { int result; @@ -421,7 +421,7 @@ int fiji_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) * @param Result the last failure code * @return result from set temperature range routine */ -int tf_fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, +static int tf_fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result) { struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); @@ -533,7 +533,7 @@ int tf_fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, * @param Result the last failure code * @return result from set temperature range routine */ -int tf_fiji_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr, +static int tf_fiji_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result) { /* If the fantable setup has failed we could have disabled diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index 789f98ad2615..14f8c1f4da3d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c @@ -24,8 +24,6 @@ #include "hwmgr.h" #include "hardwaremanager.h" #include "power_state.h" -#include "pp_acpi.h" -#include "amd_acpi.h" #include "pp_debug.h" #define PHM_FUNC_CHECK(hw) \ @@ -34,38 +32,6 @@ return -EINVAL; \ } while (0) -void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr) -{ - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableVoltageTransition); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableEngineTransition); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMemoryTransition); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGClockGating); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGCGTSSM); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLSClockGating); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_Force3DClockSupport); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLightSleep); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMCLS); - phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisablePowerGating); - - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableDPM); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableSMUUVDHandshake); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ThermalAutoThrottling); - - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); - - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_NoOD5Support); - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UserMaxClockForMultiDisplays); - - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress); - - phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM); - phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM); - - if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) && - acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION)) - phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); -} - bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr) { return hwmgr->block_hw_access; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index d829076ed9ea..524d0dd4f0e9 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c @@ -32,8 +32,8 @@ #include "pp_debug.h" #include "ppatomctrl.h" #include "ppsmc.h" - -#define VOLTAGE_SCALE 4 +#include "pp_acpi.h" +#include "amd_acpi.h" extern int cz_hwmgr_init(struct pp_hwmgr *hwmgr); extern int tonga_hwmgr_init(struct pp_hwmgr *hwmgr); @@ -41,23 +41,12 @@ extern int fiji_hwmgr_init(struct pp_hwmgr *hwmgr); extern int polaris10_hwmgr_init(struct pp_hwmgr *hwmgr); extern int iceland_hwmgr_init(struct pp_hwmgr *hwmgr); -static int hwmgr_set_features_platform_caps(struct pp_hwmgr *hwmgr) -{ - if (amdgpu_sclk_deep_sleep_en) - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkDeepSleep); - else - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkDeepSleep); - - if (amdgpu_powercontainment) - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_PowerContainment); - else - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_PowerContainment); +static void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr); +static int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr); - return 0; +uint8_t convert_to_vid(uint16_t vddc) +{ + return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25); } int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle) @@ -76,13 +65,12 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle) hwmgr->device = pp_init->device; hwmgr->chip_family = pp_init->chip_family; hwmgr->chip_id = pp_init->chip_id; - hwmgr->hw_revision = pp_init->rev_id; - hwmgr->sub_sys_id = pp_init->sub_sys_id; - hwmgr->sub_vendor_id = pp_init->sub_vendor_id; hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; hwmgr->power_source = PP_PowerSource_AC; + hwmgr->pp_table_version = PP_TABLE_V1; - hwmgr_set_features_platform_caps(hwmgr); + hwmgr_init_default_caps(hwmgr); + hwmgr_set_user_specify_caps(hwmgr); switch (hwmgr->chip_family) { case AMDGPU_FAMILY_CZ: @@ -111,8 +99,6 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle) return -EINVAL; } - phm_init_dynamic_caps(hwmgr); - return 0; } @@ -131,6 +117,8 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr) kfree(hwmgr->set_temperature_range.function_list); kfree(hwmgr->ps); + kfree(hwmgr->current_ps); + kfree(hwmgr->request_ps); kfree(hwmgr); return 0; } @@ -155,10 +143,17 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr) sizeof(struct pp_power_state); hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL); - if (hwmgr->ps == NULL) return -ENOMEM; + hwmgr->request_ps = kzalloc(size, GFP_KERNEL); + if (hwmgr->request_ps == NULL) + return -ENOMEM; + + hwmgr->current_ps = kzalloc(size, GFP_KERNEL); + if (hwmgr->current_ps == NULL) + return -ENOMEM; + state = hwmgr->ps; for (i = 0; i < table_entries; i++) { @@ -166,7 +161,8 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr) if (state->classification.flags & PP_StateClassificationFlag_Boot) { hwmgr->boot_ps = state; - hwmgr->current_ps = hwmgr->request_ps = state; + memcpy(hwmgr->current_ps, state, size); + memcpy(hwmgr->request_ps, state, size); } state->id = i + 1; /* assigned unique num for every power state id */ @@ -176,6 +172,7 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr) state = (struct pp_power_state *)((unsigned long)state + size); } + return 0; } @@ -209,8 +206,6 @@ int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index, } - - /** * Returns once the part of the register indicated by the mask has * reached the given value.The indirect space is described by giving @@ -452,6 +447,27 @@ uint8_t phm_get_voltage_index( return i - 1; } +uint8_t phm_get_voltage_id(pp_atomctrl_voltage_table *voltage_table, + uint32_t voltage) +{ + uint8_t count = (uint8_t) (voltage_table->count); + uint8_t i = 0; + + PP_ASSERT_WITH_CODE((NULL != voltage_table), + "Voltage Table empty.", return 0;); + PP_ASSERT_WITH_CODE((0 != count), + "Voltage Table empty.", return 0;); + + for (i = 0; i < count; i++) { + /* find first voltage bigger than requested */ + if (voltage_table->entries[i].value >= voltage) + return i; + } + + /* voltage is bigger than max voltage in the table */ + return i - 1; +} + uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, uint16_t vddci) { uint32_t i; @@ -539,7 +555,8 @@ int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr table_clk_vlt->entries[2].v = 810; table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_PERFORMANCE; table_clk_vlt->entries[3].v = 900; - pptable_info->vddc_dep_on_dal_pwrl = table_clk_vlt; + if (pptable_info != NULL) + pptable_info->vddc_dep_on_dal_pwrl = table_clk_vlt; hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt; } @@ -605,3 +622,94 @@ void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr) printk(KERN_ERR "DAL requested level can not" " found a available voltage in VDDC DPM Table \n"); } + +void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr) +{ + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableVoltageTransition); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableEngineTransition); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMemoryTransition); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGClockGating); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGCGTSSM); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLSClockGating); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_Force3DClockSupport); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLightSleep); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMCLS); + phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisablePowerGating); + + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableDPM); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableSMUUVDHandshake); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ThermalAutoThrottling); + + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); + + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_NoOD5Support); + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UserMaxClockForMultiDisplays); + + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress); + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM); + phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM); + + if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) && + acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION)) + phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_DynamicPatchPowerState); + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_EnableSMU7ThermalManagement); + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_DynamicPowerManagement); + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SMC); + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_DynamicUVDState); + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_FanSpeedInTableIsRPM); + + return; +} + +int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr) +{ + if (amdgpu_sclk_deep_sleep_en) + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkDeepSleep); + else + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkDeepSleep); + + if (amdgpu_powercontainment) + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_PowerContainment); + else + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_PowerContainment); + + hwmgr->feature_mask = amdgpu_pp_feature_mask; + + return 0; +} + +int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, + uint32_t sclk, uint16_t id, uint16_t *voltage) +{ + uint32_t vol; + int ret = 0; + + if (hwmgr->chip_id < CHIP_POLARIS10) { + atomctrl_get_voltage_evv_on_sclk(hwmgr, voltage_type, sclk, id, voltage); + if (*voltage >= 2000 || *voltage == 0) + *voltage = 1150; + } else { + ret = atomctrl_get_voltage_evv_on_sclk_ai(hwmgr, voltage_type, sclk, id, &vol); + *voltage = (uint16_t)vol/100; + } + return ret; +} + diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c index 8a7ada50551c..5abe43360ec0 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c @@ -781,7 +781,7 @@ static int iceland_upload_firmware(struct pp_hwmgr *hwmgr) * @param hwmgr the address of the powerplay hardware manager. * @return always 0 */ -int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) +static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) { iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend); @@ -1355,14 +1355,6 @@ static int iceland_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, return 0; } -/** - * Convert a voltage value in mv unit to VID number required by SMU firmware - */ -static uint8_t convert_to_vid(uint16_t vddc) -{ - return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25); -} - int iceland_populate_bapm_vddc_vid_sidd(struct pp_hwmgr *hwmgr) { int i; @@ -2606,7 +2598,7 @@ static int iceland_populate_smc_initial_state(struct pp_hwmgr *hwmgr) * @param pInput the pointer to input data (PowerState) * @return always 0 */ -int iceland_init_smc_table(struct pp_hwmgr *hwmgr) +static int iceland_init_smc_table(struct pp_hwmgr *hwmgr) { int result; iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend); @@ -4629,7 +4621,7 @@ static int iceland_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input) return 0; } -int iceland_update_sclk_threshold(struct pp_hwmgr *hwmgr) +static int iceland_update_sclk_threshold(struct pp_hwmgr *hwmgr) { iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c index b5edb5105986..7e405b04c2c5 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c @@ -31,7 +31,7 @@ int polaris10_phm_powerdown_uvd(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_phm_powerup_uvd(struct pp_hwmgr *hwmgr) +static int polaris10_phm_powerup_uvd(struct pp_hwmgr *hwmgr) { if (phm_cf_want_uvd_power_gating(hwmgr)) { if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, @@ -47,7 +47,7 @@ int polaris10_phm_powerup_uvd(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_phm_powerdown_vce(struct pp_hwmgr *hwmgr) +static int polaris10_phm_powerdown_vce(struct pp_hwmgr *hwmgr) { if (phm_cf_want_vce_power_gating(hwmgr)) return smum_send_msg_to_smc(hwmgr->smumgr, @@ -55,7 +55,7 @@ int polaris10_phm_powerdown_vce(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_phm_powerup_vce(struct pp_hwmgr *hwmgr) +static int polaris10_phm_powerup_vce(struct pp_hwmgr *hwmgr) { if (phm_cf_want_vce_power_gating(hwmgr)) return smum_send_msg_to_smc(hwmgr->smumgr, @@ -63,7 +63,7 @@ int polaris10_phm_powerup_vce(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_phm_powerdown_samu(struct pp_hwmgr *hwmgr) +static int polaris10_phm_powerdown_samu(struct pp_hwmgr *hwmgr) { if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SamuPowerGating)) @@ -72,7 +72,7 @@ int polaris10_phm_powerdown_samu(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_phm_powerup_samu(struct pp_hwmgr *hwmgr) +static int polaris10_phm_powerup_samu(struct pp_hwmgr *hwmgr) { if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SamuPowerGating)) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c index b69132296672..191ed504effb 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c @@ -33,11 +33,11 @@ #include "pp_debug.h" #include "ppatomctrl.h" #include "atombios.h" -#include "tonga_pptable.h" +#include "pptable_v1_0.h" #include "pppcielanes.h" #include "amd_pcie_helpers.h" #include "hardwaremanager.h" -#include "tonga_processpptables.h" +#include "process_pptables_v1_0.h" #include "cgs_common.h" #include "smu74.h" #include "smu_ucode_xfer_vi.h" @@ -108,7 +108,7 @@ enum DPM_EVENT_SRC { static const unsigned long PhwPolaris10_Magic = (unsigned long)(PHM_VIslands_Magic); -struct polaris10_power_state *cast_phw_polaris10_power_state( +static struct polaris10_power_state *cast_phw_polaris10_power_state( struct pp_hw_power_state *hw_ps) { PP_ASSERT_WITH_CODE((PhwPolaris10_Magic == hw_ps->magic), @@ -118,7 +118,8 @@ struct polaris10_power_state *cast_phw_polaris10_power_state( return (struct polaris10_power_state *)hw_ps; } -const struct polaris10_power_state *cast_const_phw_polaris10_power_state( +static const struct polaris10_power_state * +cast_const_phw_polaris10_power_state( const struct pp_hw_power_state *hw_ps) { PP_ASSERT_WITH_CODE((PhwPolaris10_Magic == hw_ps->magic), @@ -141,7 +142,7 @@ static bool polaris10_is_dpm_running(struct pp_hwmgr *hwmgr) * @param hwmgr the address of the powerplay hardware manager. * @return always 0 */ -int phm_get_mc_microcode_version (struct pp_hwmgr *hwmgr) +static int phm_get_mc_microcode_version(struct pp_hwmgr *hwmgr) { cgs_write_register(hwmgr->device, mmMC_SEQ_IO_DEBUG_INDEX, 0x9F); @@ -150,7 +151,7 @@ int phm_get_mc_microcode_version (struct pp_hwmgr *hwmgr) return 0; } -uint16_t phm_get_current_pcie_speed(struct pp_hwmgr *hwmgr) +static uint16_t phm_get_current_pcie_speed(struct pp_hwmgr *hwmgr) { uint32_t speedCntl = 0; @@ -161,7 +162,7 @@ uint16_t phm_get_current_pcie_speed(struct pp_hwmgr *hwmgr) PCIE_LC_SPEED_CNTL, LC_CURRENT_DATA_RATE)); } -int phm_get_current_pcie_lane_number(struct pp_hwmgr *hwmgr) +static int phm_get_current_pcie_lane_number(struct pp_hwmgr *hwmgr) { uint32_t link_width; @@ -181,7 +182,7 @@ int phm_get_current_pcie_lane_number(struct pp_hwmgr *hwmgr) * @param pHwMgr the address of the powerplay hardware manager. * @return always PP_Result_OK */ -int polaris10_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr) +static int polaris10_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr) { PP_ASSERT_WITH_CODE( (hwmgr->smumgr->smumgr_funcs->send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Voltage_Cntl_Enable) == 0), @@ -661,7 +662,7 @@ static int polaris10_setup_default_pcie_table(struct pp_hwmgr *hwmgr) * on the power policy or external client requests, * such as UVD request, etc. */ -int polaris10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) +static int polaris10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) { struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); struct phm_ppt_v1_information *table_info = @@ -735,11 +736,6 @@ int polaris10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) return 0; } -uint8_t convert_to_vid(uint16_t vddc) -{ - return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25); -} - /** * Mvdd table preparation for SMC. * @@ -840,7 +836,7 @@ static int polaris10_populate_cac_table(struct pp_hwmgr *hwmgr, * @return always 0 */ -int polaris10_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, +static int polaris10_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, struct SMU74_Discrete_DpmTable *table) { polaris10_populate_smc_vddci_table(hwmgr, table); @@ -1417,7 +1413,7 @@ static int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr) * @param mclk the MCLK value to be used in the decision if MVDD should be high or low. * @param voltage the SMC VOLTAGE structure to be populated */ -int polaris10_populate_mvdd_value(struct pp_hwmgr *hwmgr, +static int polaris10_populate_mvdd_value(struct pp_hwmgr *hwmgr, uint32_t mclk, SMIO_Pattern *smio_pat) { const struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); @@ -1931,7 +1927,7 @@ static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr, } -int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr) +static int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr) { struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); SMU74_Discrete_DpmTable *table = &(data->smc_state_table); @@ -2560,7 +2556,7 @@ static int polaris10_disable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) return polaris10_disable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); } -int polaris10_pcie_performance_request(struct pp_hwmgr *hwmgr) +static int polaris10_pcie_performance_request(struct pp_hwmgr *hwmgr) { struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); data->pcie_performance_request = true; @@ -2568,7 +2564,7 @@ int polaris10_pcie_performance_request(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) +static int polaris10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) { int tmp_result, result = 0; tmp_result = (!polaris10_is_dpm_running(hwmgr)) ? 0 : -1; @@ -2749,12 +2745,12 @@ int polaris10_reset_asic_tasks(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) +static int polaris10_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) { return phm_hwmgr_backend_fini(hwmgr); } -int polaris10_set_features_platform_caps(struct pp_hwmgr *hwmgr) +static int polaris10_set_features_platform_caps(struct pp_hwmgr *hwmgr) { struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); @@ -3109,7 +3105,7 @@ static int polaris10_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_patch_voltage_workaround(struct pp_hwmgr *hwmgr) +static int polaris10_patch_voltage_workaround(struct pp_hwmgr *hwmgr) { struct phm_ppt_v1_information *table_info = (struct phm_ppt_v1_information *)(hwmgr->pptable); @@ -3118,11 +3114,27 @@ int polaris10_patch_voltage_workaround(struct pp_hwmgr *hwmgr) struct phm_ppt_v1_voltage_lookup_table *lookup_table = table_info->vddc_lookup_table; uint32_t i; + uint32_t hw_revision, sub_vendor_id, sub_sys_id; + struct cgs_system_info sys_info = {0}; + + sys_info.size = sizeof(struct cgs_system_info); - if (hwmgr->chip_id == CHIP_POLARIS10 && hwmgr->hw_revision == 0xC7 && - ((hwmgr->sub_sys_id == 0xb37 && hwmgr->sub_vendor_id == 0x1002) || - (hwmgr->sub_sys_id == 0x4a8 && hwmgr->sub_vendor_id == 0x1043) || - (hwmgr->sub_sys_id == 0x9480 && hwmgr->sub_vendor_id == 0x1682))) { + sys_info.info_id = CGS_SYSTEM_INFO_PCIE_REV; + cgs_query_system_info(hwmgr->device, &sys_info); + hw_revision = (uint32_t)sys_info.value; + + sys_info.info_id = CGS_SYSTEM_INFO_PCIE_SUB_SYS_ID; + cgs_query_system_info(hwmgr->device, &sys_info); + sub_sys_id = (uint32_t)sys_info.value; + + sys_info.info_id = CGS_SYSTEM_INFO_PCIE_SUB_SYS_VENDOR_ID; + cgs_query_system_info(hwmgr->device, &sys_info); + sub_vendor_id = (uint32_t)sys_info.value; + + if (hwmgr->chip_id == CHIP_POLARIS10 && hw_revision == 0xC7 && + ((sub_sys_id == 0xb37 && sub_vendor_id == 0x1002) || + (sub_sys_id == 0x4a8 && sub_vendor_id == 0x1043) || + (sub_sys_id == 0x9480 && sub_vendor_id == 0x1682))) { if (lookup_table->entries[dep_mclk_table->entries[dep_mclk_table->count-1].vddInd].us_vdd >= 1000) return 0; @@ -3137,7 +3149,7 @@ int polaris10_patch_voltage_workaround(struct pp_hwmgr *hwmgr) } -int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) +static int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) { struct polaris10_hwmgr *data; struct pp_atomctrl_gpio_pin_assignment gpio_pin_assignment; @@ -3880,7 +3892,7 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, ps = (struct polaris10_power_state *)(&state->hardware); - result = tonga_get_powerplay_table_entry(hwmgr, entry_index, state, + result = get_powerplay_table_entry_v1_0(hwmgr, entry_index, state, polaris10_get_pp_table_entry_callback_func); /* This is the earliest time we have all the dependency table and the VBIOS boot state @@ -4347,7 +4359,8 @@ static int polaris10_generate_dpm_level_enable_mask( return 0; } -int polaris10_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable) +static int +polaris10_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable) { return smum_send_msg_to_smc(hwmgr->smumgr, enable ? PPSMC_MSG_UVDDPM_Enable : @@ -4361,7 +4374,8 @@ int polaris10_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) PPSMC_MSG_VCEDPM_Disable); } -int polaris10_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable) +static int +polaris10_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable) { return smum_send_msg_to_smc(hwmgr->smumgr, enable? PPSMC_MSG_SAMUDPM_Enable : @@ -4675,14 +4689,16 @@ static int polaris10_set_max_fan_pwm_output(struct pp_hwmgr *hwmgr, uint16_t us_ } -int polaris10_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_display) +static int +polaris10_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_display) { PPSMC_Msg msg = has_display ? (PPSMC_Msg)PPSMC_HasDisplay : (PPSMC_Msg)PPSMC_NoDisplay; return (smum_send_msg_to_smc(hwmgr->smumgr, msg) == 0) ? 0 : -1; } -int polaris10_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr) +static int +polaris10_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr) { uint32_t num_active_displays = 0; struct cgs_display_info info = {0}; @@ -4705,7 +4721,7 @@ int polaris10_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwm * @param hwmgr the address of the powerplay hardware manager. * @return always OK */ -int polaris10_program_display_gap(struct pp_hwmgr *hwmgr) +static int polaris10_program_display_gap(struct pp_hwmgr *hwmgr) { struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); uint32_t num_active_displays = 0; @@ -4750,7 +4766,7 @@ int polaris10_program_display_gap(struct pp_hwmgr *hwmgr) } -int polaris10_display_configuration_changed_task(struct pp_hwmgr *hwmgr) +static int polaris10_display_configuration_changed_task(struct pp_hwmgr *hwmgr) { return polaris10_program_display_gap(hwmgr); } @@ -4774,13 +4790,15 @@ static int polaris10_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, uint16_t us_ PPSMC_MSG_SetFanRpmMax, us_max_fan_rpm); } -int polaris10_register_internal_thermal_interrupt(struct pp_hwmgr *hwmgr, +static int +polaris10_register_internal_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *thermal_interrupt_info) { return 0; } -bool polaris10_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) +static bool polaris10_check_smc_update_required_for_display_configuration( + struct pp_hwmgr *hwmgr) { struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); bool is_update_required = false; @@ -4810,7 +4828,9 @@ static inline bool polaris10_are_power_levels_equal(const struct polaris10_perfo (pl1->pcie_lane == pl2->pcie_lane)); } -int polaris10_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal) +static int polaris10_check_states_equal(struct pp_hwmgr *hwmgr, + const struct pp_hw_power_state *pstate1, + const struct pp_hw_power_state *pstate2, bool *equal) { const struct polaris10_power_state *psa = cast_const_phw_polaris10_power_state(pstate1); const struct polaris10_power_state *psb = cast_const_phw_polaris10_power_state(pstate2); @@ -4841,7 +4861,7 @@ int polaris10_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_powe return 0; } -int polaris10_upload_mc_firmware(struct pp_hwmgr *hwmgr) +static int polaris10_upload_mc_firmware(struct pp_hwmgr *hwmgr) { struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); @@ -4954,7 +4974,7 @@ static int polaris10_init_sclk_threshold(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_setup_asic_task(struct pp_hwmgr *hwmgr) +static int polaris10_setup_asic_task(struct pp_hwmgr *hwmgr) { int tmp_result, result = 0; @@ -5225,7 +5245,7 @@ static const struct pp_hwmgr_func polaris10_hwmgr_funcs = { .get_sclk = polaris10_dpm_get_sclk, .patch_boot_state = polaris10_dpm_patch_boot_state, .get_pp_table_entry = polaris10_get_pp_table_entry, - .get_num_of_pp_table_entries = tonga_get_number_of_powerplay_table_entries, + .get_num_of_pp_table_entries = get_number_of_powerplay_table_entries_v1_0, .print_current_perforce_level = polaris10_print_current_perforce_level, .powerdown_uvd = polaris10_phm_powerdown_uvd, .powergate_uvd = polaris10_phm_powergate_uvd, @@ -5262,7 +5282,7 @@ static const struct pp_hwmgr_func polaris10_hwmgr_funcs = { int polaris10_hwmgr_init(struct pp_hwmgr *hwmgr) { hwmgr->hwmgr_func = &polaris10_hwmgr_funcs; - hwmgr->pptable_func = &tonga_pptable_funcs; + hwmgr->pptable_func = &pptable_v1_0_funcs; pp_polaris10_thermal_initialize(hwmgr); return 0; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h index 33c33947e827..378ab342c257 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h @@ -30,6 +30,7 @@ #include "ppatomctrl.h" #include "polaris10_ppsmc.h" #include "polaris10_powertune.h" +#include "polaris10_smumgr.h" #define POLARIS10_MAX_HARDWARE_POWERLEVELS 2 @@ -165,10 +166,6 @@ struct polaris10_pcie_perf_range { uint16_t max; uint16_t min; }; -struct polaris10_range_table { - uint32_t trans_lower_frequency; /* in 10khz */ - uint32_t trans_upper_frequency; -}; struct polaris10_hwmgr { struct polaris10_dpm_table dpm_table; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.h index bc78e28f010d..329119d6cc71 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.h @@ -66,19 +66,6 @@ struct polaris10_pt_config_reg { enum polaris10_pt_config_reg_type type; }; -struct polaris10_pt_defaults { - uint8_t SviLoadLineEn; - uint8_t SviLoadLineVddC; - uint8_t TDC_VDDC_ThrottleReleaseLimitPerc; - uint8_t TDC_MAWt; - uint8_t TdcWaterfallCtl; - uint8_t DTEAmbientTempBase; - - uint32_t DisplayCac; - uint32_t BAPM_TEMP_GRADIENT; - uint16_t BAPMTI_R[SMU74_DTE_ITERATIONS * SMU74_DTE_SOURCES * SMU74_DTE_SINKS]; - uint16_t BAPMTI_RC[SMU74_DTE_ITERATIONS * SMU74_DTE_SOURCES * SMU74_DTE_SINKS]; -}; void polaris10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr); int polaris10_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_thermal.c index b206632d4650..41f835adba91 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_thermal.c @@ -152,7 +152,7 @@ int polaris10_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr) +static int polaris10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr) { int result; @@ -425,7 +425,7 @@ int polaris10_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) * @param Result the last failure code * @return result from set temperature range routine */ -int tf_polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, +static int tf_polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result) { struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); @@ -537,7 +537,7 @@ int tf_polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, * @param Result the last failure code * @return result from set temperature range routine */ -int tf_polaris10_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr, +static int tf_polaris10_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result) { /* If the fantable setup has failed we could have disabled diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h b/drivers/gpu/drm/amd/powerplay/hwmgr/pptable_v1_0.h index f127198aafc4..1e870f58dd12 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pptable_v1_0.h @@ -164,7 +164,7 @@ typedef struct _ATOM_Tonga_State { typedef struct _ATOM_Tonga_State_Array { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_State states[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_State entries[1]; /* Dynamically allocate entries. */ } ATOM_Tonga_State_Array; typedef struct _ATOM_Tonga_MCLK_Dependency_Record { diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c index a0ffd4a73d8c..7de701d8a450 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c @@ -23,13 +23,13 @@ #include <linux/module.h> #include <linux/slab.h> -#include "tonga_processpptables.h" +#include "process_pptables_v1_0.h" #include "ppatomctrl.h" #include "atombios.h" #include "pp_debug.h" #include "hwmgr.h" #include "cgs_common.h" -#include "tonga_pptable.h" +#include "pptable_v1_0.h" /** * Private Function used during initialization. @@ -153,12 +153,14 @@ const void *get_powerplay_table(struct pp_hwmgr *hwmgr) static int get_vddc_lookup_table( struct pp_hwmgr *hwmgr, phm_ppt_v1_voltage_lookup_table **lookup_table, - const ATOM_Tonga_Voltage_Lookup_Table *vddc_lookup_pp_tables, - uint32_t max_levels + const ATOM_Tonga_Voltage_Lookup_Table *vddc_lookup_pp_tables, + uint32_t max_levels ) { uint32_t table_size, i; phm_ppt_v1_voltage_lookup_table *table; + phm_ppt_v1_voltage_lookup_record *record; + ATOM_Tonga_Voltage_Lookup_Record *atom_record; PP_ASSERT_WITH_CODE((0 != vddc_lookup_pp_tables->ucNumEntries), "Invalid CAC Leakage PowerPlay Table!", return 1); @@ -176,15 +178,17 @@ static int get_vddc_lookup_table( table->count = vddc_lookup_pp_tables->ucNumEntries; for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++) { - table->entries[i].us_calculated = 0; - table->entries[i].us_vdd = - vddc_lookup_pp_tables->entries[i].usVdd; - table->entries[i].us_cac_low = - vddc_lookup_pp_tables->entries[i].usCACLow; - table->entries[i].us_cac_mid = - vddc_lookup_pp_tables->entries[i].usCACMid; - table->entries[i].us_cac_high = - vddc_lookup_pp_tables->entries[i].usCACHigh; + record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + phm_ppt_v1_voltage_lookup_record, + entries, table, i); + atom_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_Voltage_Lookup_Record, + entries, vddc_lookup_pp_tables, i); + record->us_calculated = 0; + record->us_vdd = atom_record->usVdd; + record->us_cac_low = atom_record->usCACLow; + record->us_cac_mid = atom_record->usCACMid; + record->us_cac_high = atom_record->usCACHigh; } *lookup_table = table; @@ -313,11 +317,12 @@ static int init_dpm_2_parameters( static int get_valid_clk( struct pp_hwmgr *hwmgr, struct phm_clock_array **clk_table, - const phm_ppt_v1_clock_voltage_dependency_table * clk_volt_pp_table + phm_ppt_v1_clock_voltage_dependency_table const *clk_volt_pp_table ) { uint32_t table_size, i; struct phm_clock_array *table; + phm_ppt_v1_clock_voltage_dependency_record *dep_record; PP_ASSERT_WITH_CODE((0 != clk_volt_pp_table->count), "Invalid PowerPlay Table!", return -1); @@ -334,9 +339,12 @@ static int get_valid_clk( table->count = (uint32_t)clk_volt_pp_table->count; - for (i = 0; i < table->count; i++) - table->values[i] = (uint32_t)clk_volt_pp_table->entries[i].clk; - + for (i = 0; i < table->count; i++) { + dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + phm_ppt_v1_clock_voltage_dependency_record, + entries, clk_volt_pp_table, i); + table->values[i] = (uint32_t)dep_record->clk; + } *clk_table = table; return 0; @@ -345,7 +353,7 @@ static int get_valid_clk( static int get_hard_limits( struct pp_hwmgr *hwmgr, struct phm_clock_and_voltage_limits *limits, - const ATOM_Tonga_Hard_Limit_Table * limitable + ATOM_Tonga_Hard_Limit_Table const *limitable ) { PP_ASSERT_WITH_CODE((0 != limitable->ucNumEntries), "Invalid PowerPlay Table!", return -1); @@ -363,11 +371,13 @@ static int get_hard_limits( static int get_mclk_voltage_dependency_table( struct pp_hwmgr *hwmgr, phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_mclk_dep_table, - const ATOM_Tonga_MCLK_Dependency_Table * mclk_dep_table + ATOM_Tonga_MCLK_Dependency_Table const *mclk_dep_table ) { uint32_t table_size, i; phm_ppt_v1_clock_voltage_dependency_table *mclk_table; + phm_ppt_v1_clock_voltage_dependency_record *mclk_table_record; + ATOM_Tonga_MCLK_Dependency_Record *mclk_dep_record; PP_ASSERT_WITH_CODE((0 != mclk_dep_table->ucNumEntries), "Invalid PowerPlay Table!", return -1); @@ -385,16 +395,17 @@ static int get_mclk_voltage_dependency_table( mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries; for (i = 0; i < mclk_dep_table->ucNumEntries; i++) { - mclk_table->entries[i].vddInd = - mclk_dep_table->entries[i].ucVddcInd; - mclk_table->entries[i].vdd_offset = - mclk_dep_table->entries[i].usVddgfxOffset; - mclk_table->entries[i].vddci = - mclk_dep_table->entries[i].usVddci; - mclk_table->entries[i].mvdd = - mclk_dep_table->entries[i].usMvdd; - mclk_table->entries[i].clk = - mclk_dep_table->entries[i].ulMclk; + mclk_table_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + phm_ppt_v1_clock_voltage_dependency_record, + entries, mclk_table, i); + mclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_MCLK_Dependency_Record, + entries, mclk_dep_table, i); + mclk_table_record->vddInd = mclk_dep_record->ucVddcInd; + mclk_table_record->vdd_offset = mclk_dep_record->usVddgfxOffset; + mclk_table_record->vddci = mclk_dep_record->usVddci; + mclk_table_record->mvdd = mclk_dep_record->usMvdd; + mclk_table_record->clk = mclk_dep_record->ulMclk; } *pp_tonga_mclk_dep_table = mclk_table; @@ -405,15 +416,17 @@ static int get_mclk_voltage_dependency_table( static int get_sclk_voltage_dependency_table( struct pp_hwmgr *hwmgr, phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table, - const PPTable_Generic_SubTable_Header *sclk_dep_table + PPTable_Generic_SubTable_Header const *sclk_dep_table ) { uint32_t table_size, i; phm_ppt_v1_clock_voltage_dependency_table *sclk_table; + phm_ppt_v1_clock_voltage_dependency_record *sclk_table_record; if (sclk_dep_table->ucRevId < 1) { const ATOM_Tonga_SCLK_Dependency_Table *tonga_table = (ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table; + ATOM_Tonga_SCLK_Dependency_Record *sclk_dep_record; PP_ASSERT_WITH_CODE((0 != tonga_table->ucNumEntries), "Invalid PowerPlay Table!", return -1); @@ -431,20 +444,23 @@ static int get_sclk_voltage_dependency_table( sclk_table->count = (uint32_t)tonga_table->ucNumEntries; for (i = 0; i < tonga_table->ucNumEntries; i++) { - sclk_table->entries[i].vddInd = - tonga_table->entries[i].ucVddInd; - sclk_table->entries[i].vdd_offset = - tonga_table->entries[i].usVddcOffset; - sclk_table->entries[i].clk = - tonga_table->entries[i].ulSclk; - sclk_table->entries[i].cks_enable = - (((tonga_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; - sclk_table->entries[i].cks_voffset = - (tonga_table->entries[i].ucCKSVOffsetandDisable & 0x7F); + sclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_SCLK_Dependency_Record, + entries, tonga_table, i); + sclk_table_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + phm_ppt_v1_clock_voltage_dependency_record, + entries, sclk_table, i); + sclk_table_record->vddInd = sclk_dep_record->ucVddInd; + sclk_table_record->vdd_offset = sclk_dep_record->usVddcOffset; + sclk_table_record->clk = sclk_dep_record->ulSclk; + sclk_table_record->cks_enable = + (((sclk_dep_record->ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; + sclk_table_record->cks_voffset = (sclk_dep_record->ucCKSVOffsetandDisable & 0x7F); } } else { const ATOM_Polaris_SCLK_Dependency_Table *polaris_table = (ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table; + ATOM_Polaris_SCLK_Dependency_Record *sclk_dep_record; PP_ASSERT_WITH_CODE((0 != polaris_table->ucNumEntries), "Invalid PowerPlay Table!", return -1); @@ -462,17 +478,19 @@ static int get_sclk_voltage_dependency_table( sclk_table->count = (uint32_t)polaris_table->ucNumEntries; for (i = 0; i < polaris_table->ucNumEntries; i++) { - sclk_table->entries[i].vddInd = - polaris_table->entries[i].ucVddInd; - sclk_table->entries[i].vdd_offset = - polaris_table->entries[i].usVddcOffset; - sclk_table->entries[i].clk = - polaris_table->entries[i].ulSclk; - sclk_table->entries[i].cks_enable = - (((polaris_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; - sclk_table->entries[i].cks_voffset = - (polaris_table->entries[i].ucCKSVOffsetandDisable & 0x7F); - sclk_table->entries[i].sclk_offset = polaris_table->entries[i].ulSclkOffset; + sclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Polaris_SCLK_Dependency_Record, + entries, polaris_table, i); + sclk_table_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + phm_ppt_v1_clock_voltage_dependency_record, + entries, sclk_table, i); + sclk_table_record->vddInd = sclk_dep_record->ucVddInd; + sclk_table_record->vdd_offset = sclk_dep_record->usVddcOffset; + sclk_table_record->clk = sclk_dep_record->ulSclk; + sclk_table_record->cks_enable = + (((sclk_dep_record->ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; + sclk_table_record->cks_voffset = (sclk_dep_record->ucCKSVOffsetandDisable & 0x7F); + sclk_table_record->sclk_offset = sclk_dep_record->ulSclkOffset; } } *pp_tonga_sclk_dep_table = sclk_table; @@ -483,16 +501,19 @@ static int get_sclk_voltage_dependency_table( static int get_pcie_table( struct pp_hwmgr *hwmgr, phm_ppt_v1_pcie_table **pp_tonga_pcie_table, - const PPTable_Generic_SubTable_Header * pTable + PPTable_Generic_SubTable_Header const *ptable ) { uint32_t table_size, i, pcie_count; phm_ppt_v1_pcie_table *pcie_table; struct phm_ppt_v1_information *pp_table_information = (struct phm_ppt_v1_information *)(hwmgr->pptable); + phm_ppt_v1_pcie_record *pcie_record; + + if (ptable->ucRevId < 1) { + const ATOM_Tonga_PCIE_Table *atom_pcie_table = (ATOM_Tonga_PCIE_Table *)ptable; + ATOM_Tonga_PCIE_Record *atom_pcie_record; - if (pTable->ucRevId < 1) { - const ATOM_Tonga_PCIE_Table *atom_pcie_table = (ATOM_Tonga_PCIE_Table *)pTable; PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0), "Invalid PowerPlay Table!", return -1); @@ -518,18 +539,23 @@ static int get_pcie_table( Disregarding the excess entries... \n"); pcie_table->count = pcie_count; - for (i = 0; i < pcie_count; i++) { - pcie_table->entries[i].gen_speed = - atom_pcie_table->entries[i].ucPCIEGenSpeed; - pcie_table->entries[i].lane_width = - atom_pcie_table->entries[i].usPCIELaneWidth; + pcie_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + phm_ppt_v1_pcie_record, + entries, pcie_table, i); + atom_pcie_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_PCIE_Record, + entries, atom_pcie_table, i); + pcie_record->gen_speed = atom_pcie_record->ucPCIEGenSpeed; + pcie_record->lane_width = atom_pcie_record->usPCIELaneWidth; } *pp_tonga_pcie_table = pcie_table; } else { /* Polaris10/Polaris11 and newer. */ - const ATOM_Polaris10_PCIE_Table *atom_pcie_table = (ATOM_Polaris10_PCIE_Table *)pTable; + const ATOM_Polaris10_PCIE_Table *atom_pcie_table = (ATOM_Polaris10_PCIE_Table *)ptable; + ATOM_Polaris10_PCIE_Record *atom_pcie_record; + PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0), "Invalid PowerPlay Table!", return -1); @@ -557,12 +583,15 @@ static int get_pcie_table( pcie_table->count = pcie_count; for (i = 0; i < pcie_count; i++) { - pcie_table->entries[i].gen_speed = - atom_pcie_table->entries[i].ucPCIEGenSpeed; - pcie_table->entries[i].lane_width = - atom_pcie_table->entries[i].usPCIELaneWidth; - pcie_table->entries[i].pcie_sclk = - atom_pcie_table->entries[i].ulPCIE_Sclk; + pcie_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + phm_ppt_v1_pcie_record, + entries, pcie_table, i); + atom_pcie_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Polaris10_PCIE_Record, + entries, atom_pcie_table, i); + pcie_record->gen_speed = atom_pcie_record->ucPCIEGenSpeed; + pcie_record->lane_width = atom_pcie_record->usPCIELaneWidth; + pcie_record->pcie_sclk = atom_pcie_record->ulPCIE_Sclk; } *pp_tonga_pcie_table = pcie_table; @@ -684,6 +713,7 @@ static int get_mm_clock_voltage_table( uint32_t table_size, i; const ATOM_Tonga_MM_Dependency_Record *mm_dependency_record; phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table; + phm_ppt_v1_mm_clock_voltage_dependency_record *mm_table_record; PP_ASSERT_WITH_CODE((0 != mm_dependency_table->ucNumEntries), "Invalid PowerPlay Table!", return -1); @@ -700,14 +730,19 @@ static int get_mm_clock_voltage_table( mm_table->count = mm_dependency_table->ucNumEntries; for (i = 0; i < mm_dependency_table->ucNumEntries; i++) { - mm_dependency_record = &mm_dependency_table->entries[i]; - mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd; - mm_table->entries[i].vddgfx_offset = mm_dependency_record->usVddgfxOffset; - mm_table->entries[i].aclk = mm_dependency_record->ulAClk; - mm_table->entries[i].samclock = mm_dependency_record->ulSAMUClk; - mm_table->entries[i].eclk = mm_dependency_record->ulEClk; - mm_table->entries[i].vclk = mm_dependency_record->ulVClk; - mm_table->entries[i].dclk = mm_dependency_record->ulDClk; + mm_dependency_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_MM_Dependency_Record, + entries, mm_dependency_table, i); + mm_table_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + phm_ppt_v1_mm_clock_voltage_dependency_record, + entries, mm_table, i); + mm_table_record->vddcInd = mm_dependency_record->ucVddcInd; + mm_table_record->vddgfx_offset = mm_dependency_record->usVddgfxOffset; + mm_table_record->aclk = mm_dependency_record->ulAClk; + mm_table_record->samclock = mm_dependency_record->ulSAMUClk; + mm_table_record->eclk = mm_dependency_record->ulEClk; + mm_table_record->vclk = mm_dependency_record->ulVClk; + mm_table_record->dclk = mm_dependency_record->ulDClk; } *tonga_mm_table = mm_table; @@ -1014,7 +1049,7 @@ static int check_powerplay_tables( return 0; } -int tonga_pp_tables_initialize(struct pp_hwmgr *hwmgr) +int pp_tables_v1_0_initialize(struct pp_hwmgr *hwmgr) { int result = 0; const ATOM_Tonga_POWERPLAYTABLE *powerplay_table; @@ -1065,7 +1100,7 @@ int tonga_pp_tables_initialize(struct pp_hwmgr *hwmgr) return result; } -int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) +int pp_tables_v1_0_uninitialize(struct pp_hwmgr *hwmgr) { struct phm_ppt_v1_information *pp_table_information = (struct phm_ppt_v1_information *)(hwmgr->pptable); @@ -1109,14 +1144,14 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) return 0; } -const struct pp_table_func tonga_pptable_funcs = { - .pptable_init = tonga_pp_tables_initialize, - .pptable_fini = tonga_pp_tables_uninitialize, +const struct pp_table_func pptable_v1_0_funcs = { + .pptable_init = pp_tables_v1_0_initialize, + .pptable_fini = pp_tables_v1_0_uninitialize, }; -int tonga_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr) +int get_number_of_powerplay_table_entries_v1_0(struct pp_hwmgr *hwmgr) { - const ATOM_Tonga_State_Array * state_arrays; + ATOM_Tonga_State_Array const *state_arrays; const ATOM_Tonga_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr); PP_ASSERT_WITH_CODE((NULL != pp_table), @@ -1163,6 +1198,71 @@ static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr, return result; } +static int ppt_get_num_of_vce_state_table_entries_v1_0(struct pp_hwmgr *hwmgr) +{ + const ATOM_Tonga_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr); + const ATOM_Tonga_VCE_State_Table *vce_state_table = + (ATOM_Tonga_VCE_State_Table *)(((unsigned long)pp_table) + le16_to_cpu(pp_table->usVCEStateTableOffset)); + + if (vce_state_table == NULL) + return 0; + + return vce_state_table->ucNumEntries; +} + +static int ppt_get_vce_state_table_entry_v1_0(struct pp_hwmgr *hwmgr, uint32_t i, + struct pp_vce_state *vce_state, void **clock_info, uint32_t *flag) +{ + const ATOM_Tonga_VCE_State_Record *vce_state_record; + ATOM_Tonga_SCLK_Dependency_Record *sclk_dep_record; + ATOM_Tonga_MCLK_Dependency_Record *mclk_dep_record; + ATOM_Tonga_MM_Dependency_Record *mm_dep_record; + const ATOM_Tonga_POWERPLAYTABLE *pptable = get_powerplay_table(hwmgr); + const ATOM_Tonga_VCE_State_Table *vce_state_table = (ATOM_Tonga_VCE_State_Table *)(((unsigned long)pptable) + + le16_to_cpu(pptable->usVCEStateTableOffset)); + const ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = (ATOM_Tonga_SCLK_Dependency_Table *)(((unsigned long)pptable) + + le16_to_cpu(pptable->usSclkDependencyTableOffset)); + const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = (ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long)pptable) + + le16_to_cpu(pptable->usMclkDependencyTableOffset)); + const ATOM_Tonga_MM_Dependency_Table *mm_dep_table = (ATOM_Tonga_MM_Dependency_Table *)(((unsigned long)pptable) + + le16_to_cpu(pptable->usMMDependencyTableOffset)); + + PP_ASSERT_WITH_CODE((i < vce_state_table->ucNumEntries), + "Requested state entry ID is out of range!", + return -EINVAL); + + vce_state_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_VCE_State_Record, + entries, vce_state_table, i); + sclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_SCLK_Dependency_Record, + entries, sclk_dep_table, + vce_state_record->ucSCLKIndex); + mm_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_MM_Dependency_Record, + entries, mm_dep_table, + vce_state_record->ucVCEClockIndex); + *flag = vce_state_record->ucFlag; + + vce_state->evclk = mm_dep_record->ulEClk; + vce_state->ecclk = mm_dep_record->ulEClk; + vce_state->sclk = sclk_dep_record->ulSclk; + + if (vce_state_record->ucMCLKIndex >= mclk_dep_table->ucNumEntries) + mclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_MCLK_Dependency_Record, + entries, mclk_dep_table, + mclk_dep_table->ucNumEntries - 1); + else + mclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_MCLK_Dependency_Record, + entries, mclk_dep_table, + vce_state_record->ucMCLKIndex); + + vce_state->mclk = mclk_dep_record->ulMclk; + return 0; +} + /** * Create a Power State out of an entry in the PowerPlay table. * This function is called by the hardware back-end. @@ -1171,15 +1271,17 @@ static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr, * @param power_state The address of the PowerState instance being created. * @return -1 if the entry cannot be retrieved. */ -int tonga_get_powerplay_table_entry(struct pp_hwmgr *hwmgr, +int get_powerplay_table_entry_v1_0(struct pp_hwmgr *hwmgr, uint32_t entry_index, struct pp_power_state *power_state, int (*call_back_func)(struct pp_hwmgr *, void *, struct pp_power_state *, void *, uint32_t)) { int result = 0; - const ATOM_Tonga_State_Array * state_arrays; + const ATOM_Tonga_State_Array *state_arrays; const ATOM_Tonga_State *state_entry; const ATOM_Tonga_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr); + int i, j; + uint32_t flags = 0; PP_ASSERT_WITH_CODE((NULL != pp_table), "Missing PowerPlay Table!", return -1;); power_state->classification.bios_index = entry_index; @@ -1196,7 +1298,9 @@ int tonga_get_powerplay_table_entry(struct pp_hwmgr *hwmgr, PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries), "Invalid PowerPlay Table State Array Entry.", return -1); - state_entry = &(state_arrays->states[entry_index]); + state_entry = GET_FLEXIBLE_ARRAY_MEMBER_ADDR( + ATOM_Tonga_State, entries, + state_arrays, entry_index); result = call_back_func(hwmgr, (void *)state_entry, power_state, (void *)pp_table, @@ -1209,5 +1313,13 @@ int tonga_get_powerplay_table_entry(struct pp_hwmgr *hwmgr, PP_StateClassificationFlag_Boot)) result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware)); + hwmgr->num_vce_state_tables = i = ppt_get_num_of_vce_state_table_entries_v1_0(hwmgr); + + if ((i != 0) && (i <= PP_MAX_VCE_LEVELS)) { + for (j = 0; j < i; j++) + ppt_get_vce_state_table_entry_v1_0(hwmgr, j, &(hwmgr->vce_states[j]), NULL, &flags); + } + return result; } + diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.h b/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.h index d24b8887f466..b9710abdff01 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.h @@ -20,14 +20,14 @@ * OTHER DEALINGS IN THE SOFTWARE. * */ -#ifndef TONGA_PROCESSPPTABLES_H -#define TONGA_PROCESSPPTABLES_H +#ifndef _PROCESSPPTABLES_V1_0_H +#define _PROCESSPPTABLES_V1_0_H #include "hwmgr.h" -extern const struct pp_table_func tonga_pptable_funcs; -extern int tonga_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr); -extern int tonga_get_powerplay_table_entry(struct pp_hwmgr *hwmgr, uint32_t entry_index, +extern const struct pp_table_func pptable_v1_0_funcs; +extern int get_number_of_powerplay_table_entries_v1_0(struct pp_hwmgr *hwmgr); +extern int get_powerplay_table_entry_v1_0(struct pp_hwmgr *hwmgr, uint32_t entry_index, struct pp_power_state *power_state, int (*call_back_func)(struct pp_hwmgr *, void *, struct pp_power_state *, void *, uint32_t)); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c index 6c321b0d8a1e..ccf7ebeaf892 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c @@ -1523,7 +1523,7 @@ int get_number_of_vce_state_table_entries( int get_vce_state_table_entry(struct pp_hwmgr *hwmgr, unsigned long i, - struct PP_VCEState *vce_state, + struct pp_vce_state *vce_state, void **clock_info, unsigned long *flag) { diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 7f9ba7f15e19..582d04aed346 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c @@ -29,8 +29,8 @@ #include "tonga_hwmgr.h" #include "pptable.h" #include "processpptables.h" -#include "tonga_processpptables.h" -#include "tonga_pptable.h" +#include "process_pptables_v1_0.h" +#include "pptable_v1_0.h" #include "pp_debug.h" #include "tonga_ppsmc.h" #include "cgs_common.h" @@ -202,6 +202,7 @@ uint8_t tonga_get_voltage_id(pp_atomctrl_voltage_table *voltage_table, return i - 1; } + /** * @brief PhwTonga_GetVoltageOrder * Returns index of requested voltage record in lookup(table) @@ -229,7 +230,7 @@ uint8_t tonga_get_voltage_index(phm_ppt_v1_voltage_lookup_table *look_up_table, return i-1; } -bool tonga_is_dpm_running(struct pp_hwmgr *hwmgr) +static bool tonga_is_dpm_running(struct pp_hwmgr *hwmgr) { /* * We return the status of Voltage Control instead of checking SCLK/MCLK DPM @@ -334,7 +335,7 @@ void tonga_initialize_dpm_defaults(struct pp_hwmgr *hwmgr) } -int tonga_update_sclk_threshold(struct pp_hwmgr *hwmgr) +static int tonga_update_sclk_threshold(struct pp_hwmgr *hwmgr) { tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend); @@ -771,7 +772,7 @@ int tonga_set_boot_state(struct pp_hwmgr *hwmgr) * @param hwmgr the address of the powerplay hardware manager. * @return always 0 */ -int tonga_process_firmware_header(struct pp_hwmgr *hwmgr) +static int tonga_process_firmware_header(struct pp_hwmgr *hwmgr) { tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend); struct tonga_smumgr *tonga_smu = (struct tonga_smumgr *)(hwmgr->smumgr->backend); @@ -1315,15 +1316,6 @@ static int tonga_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, } /** - * Convert a voltage value in mv unit to VID number required by SMU firmware - */ -static uint8_t convert_to_vid(uint16_t vddc) -{ - return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25); -} - - -/** * Preparation of vddc and vddgfx CAC tables for SMC. * * @param hwmgr the address of the hardware manager @@ -2894,7 +2886,7 @@ int tonga_populate_smc_initial_state(struct pp_hwmgr *hwmgr, * @param pInput the pointer to input data (PowerState) * @return always 0 */ -int tonga_init_smc_table(struct pp_hwmgr *hwmgr) +static int tonga_init_smc_table(struct pp_hwmgr *hwmgr) { int result; tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend); @@ -3989,7 +3981,7 @@ int tonga_set_valid_flag(phw_tonga_mc_reg_table *table) return 0; } -int tonga_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) +static int tonga_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) { int result; tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend); @@ -4326,6 +4318,79 @@ int tonga_program_voting_clients(struct pp_hwmgr *hwmgr) return 0; } +static void tonga_set_dpm_event_sources(struct pp_hwmgr *hwmgr, uint32_t sources) +{ + bool protection; + enum DPM_EVENT_SRC src; + + switch (sources) { + default: + printk(KERN_ERR "Unknown throttling event sources."); + /* fall through */ + case 0: + protection = false; + /* src is unused */ + break; + case (1 << PHM_AutoThrottleSource_Thermal): + protection = true; + src = DPM_EVENT_SRC_DIGITAL; + break; + case (1 << PHM_AutoThrottleSource_External): + protection = true; + src = DPM_EVENT_SRC_EXTERNAL; + break; + case (1 << PHM_AutoThrottleSource_External) | + (1 << PHM_AutoThrottleSource_Thermal): + protection = true; + src = DPM_EVENT_SRC_DIGITAL_OR_EXTERNAL; + break; + } + /* Order matters - don't enable thermal protection for the wrong source. */ + if (protection) { + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_CTRL, + DPM_EVENT_SRC, src); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, + THERMAL_PROTECTION_DIS, + !phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ThermalController)); + } else + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, + THERMAL_PROTECTION_DIS, 1); +} + +static int tonga_enable_auto_throttle_source(struct pp_hwmgr *hwmgr, + PHM_AutoThrottleSource source) +{ + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); + + if (!(data->active_auto_throttle_sources & (1 << source))) { + data->active_auto_throttle_sources |= 1 << source; + tonga_set_dpm_event_sources(hwmgr, data->active_auto_throttle_sources); + } + return 0; +} + +static int tonga_enable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) +{ + return tonga_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); +} + +static int tonga_disable_auto_throttle_source(struct pp_hwmgr *hwmgr, + PHM_AutoThrottleSource source) +{ + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); + + if (data->active_auto_throttle_sources & (1 << source)) { + data->active_auto_throttle_sources &= ~(1 << source); + tonga_set_dpm_event_sources(hwmgr, data->active_auto_throttle_sources); + } + return 0; +} + +static int tonga_disable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) +{ + return tonga_disable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); +} int tonga_enable_dpm_tasks(struct pp_hwmgr *hwmgr) { @@ -4409,6 +4474,10 @@ int tonga_enable_dpm_tasks(struct pp_hwmgr *hwmgr) PP_ASSERT_WITH_CODE((tmp_result == 0), "Failed to power control set level!", result = tmp_result); + tmp_result = tonga_enable_thermal_auto_throttle(hwmgr); + PP_ASSERT_WITH_CODE((0 == tmp_result), + "Failed to enable thermal auto throttle!", result = tmp_result); + return result; } @@ -4420,6 +4489,10 @@ int tonga_disable_dpm_tasks(struct pp_hwmgr *hwmgr) PP_ASSERT_WITH_CODE((0 == tmp_result), "SMC is still running!", return 0); + tmp_result = tonga_disable_thermal_auto_throttle(hwmgr); + PP_ASSERT_WITH_CODE((tmp_result == 0), + "Failed to disable thermal auto throttle!", result = tmp_result); + tmp_result = tonga_stop_dpm(hwmgr); PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to stop DPM!", result = tmp_result); @@ -5090,7 +5163,7 @@ static int tonga_get_pp_table_entry(struct pp_hwmgr *hwmgr, tonga_ps = cast_phw_tonga_power_state(&(ps->hardware)); - result = tonga_get_powerplay_table_entry(hwmgr, entry_index, ps, + result = get_powerplay_table_entry_v1_0(hwmgr, entry_index, ps, tonga_get_pp_table_entry_callback_func); /* This is the earliest time we have all the dependency table and the VBIOS boot state @@ -6254,7 +6327,7 @@ static const struct pp_hwmgr_func tonga_hwmgr_funcs = { .get_sclk = tonga_dpm_get_sclk, .patch_boot_state = tonga_dpm_patch_boot_state, .get_pp_table_entry = tonga_get_pp_table_entry, - .get_num_of_pp_table_entries = tonga_get_number_of_powerplay_table_entries, + .get_num_of_pp_table_entries = get_number_of_powerplay_table_entries_v1_0, .print_current_perforce_level = tonga_print_current_perforce_level, .powerdown_uvd = tonga_phm_powerdown_uvd, .powergate_uvd = tonga_phm_powergate_uvd, @@ -6290,7 +6363,7 @@ static const struct pp_hwmgr_func tonga_hwmgr_funcs = { int tonga_hwmgr_init(struct pp_hwmgr *hwmgr) { hwmgr->hwmgr_func = &tonga_hwmgr_funcs; - hwmgr->pptable_func = &tonga_pptable_funcs; + hwmgr->pptable_func = &pptable_v1_0_funcs; pp_tonga_thermal_initialize(hwmgr); return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c index 9496ade3247e..24d9a05e7997 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c @@ -56,9 +56,6 @@ void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) else tonga_hwmgr->power_tune_defaults = &tonga_power_tune_data_set_array[0]; - /* Assume disabled */ - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_PowerContainment); phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_CAC); phm_cap_unset(hwmgr->platform_descriptor.platformCaps, |