diff options
author | Dave Airlie <airlied@redhat.com> | 2016-09-20 06:17:38 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-09-20 06:17:38 +1000 |
commit | bd4a68da1989a3735b9c183422effc177e2d5ae8 (patch) | |
tree | a7ad047fc3ecebdeb2f671c6d0710b44155e21b9 /drivers/gpu/drm/amd/powerplay | |
parent | 9f8cf165c62913244479832f04c44cd77ffc9293 (diff) | |
parent | af1f85ddecfa341e684db950c34a1813d36750db (diff) | |
download | kernel_replicant_linux-bd4a68da1989a3735b9c183422effc177e2d5ae8.tar.gz kernel_replicant_linux-bd4a68da1989a3735b9c183422effc177e2d5ae8.tar.bz2 kernel_replicant_linux-bd4a68da1989a3735b9c183422effc177e2d5ae8.zip |
Merge branch 'drm-next-4.9' of git://people.freedesktop.org/~agd5f/linux into drm-next
More radeon and amdgpu changes for 4.9. Highlights:
- Initial SI support for amdgpu (controlled by a Kconfig option)
- misc ttm cleanups
- runtimepm fixes
- S3/S4 fixes
- power improvements
- lots of code cleanups and optimizations
* 'drm-next-4.9' of git://people.freedesktop.org/~agd5f/linux: (151 commits)
drm/ttm: remove cpu_address member from ttm_tt
drm/radeon/radeon_device: remove unused function
drm/amdgpu: clean function declarations in amdgpu_ttm.c up
drm/amdgpu: use the new ring ib and dma frame size callbacks (v2)
drm/amdgpu/vce3: add ring callbacks for ib and dma frame size
drm/amdgpu/vce2: add ring callbacks for ib and dma frame size
drm/amdgpu/vce: add common ring callbacks for ib and dma frame size
drm/amdgpu/uvd6: add ring callbacks for ib and dma frame size
drm/amdgpu/uvd5: add ring callbacks for ib and dma frame size
drm/amdgpu/uvd4.2: add ring callbacks for ib and dma frame size
drm/amdgpu/sdma3: add ring callbacks for ib and dma frame size
drm/amdgpu/sdma2.4: add ring callbacks for ib and dma frame size
drm/amdgpu/cik_sdma: add ring callbacks for ib and dma frame size
drm/amdgpu/si_dma: add ring callbacks for ib and dma frame size
drm/amdgpu/gfx8: add ring callbacks for ib and dma frame size
drm/amdgpu/gfx7: add ring callbacks for ib and dma frame size
drm/amdgpu/gfx6: add ring callbacks for ib and dma frame size
drm/amdgpu/ring: add an interface to get dma frame and ib size
drm/amdgpu/sdma3: drop unused functions
drm/amdgpu/gfx6: drop gds_switch callback
...
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay')
29 files changed, 642 insertions, 353 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 2de34a5a85c2..b1d19409bf86 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -538,7 +538,6 @@ int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id, void *input, ret = pem_handle_event(pp_handle->eventmgr, event_id, &data); break; case AMD_PP_EVENT_READJUST_POWER_STATE: - pp_handle->hwmgr->current_ps = pp_handle->hwmgr->boot_ps; ret = pem_handle_event(pp_handle->eventmgr, event_id, &data); break; default: @@ -765,15 +764,12 @@ static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) PP_CHECK_HW(hwmgr); if (!hwmgr->hardcode_pp_table) { - hwmgr->hardcode_pp_table = - kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL); + hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table, + hwmgr->soft_pp_table_size, + GFP_KERNEL); if (!hwmgr->hardcode_pp_table) return -ENOMEM; - - /* to avoid powerplay crash when hardcode pptable is empty */ - memcpy(hwmgr->hardcode_pp_table, hwmgr->soft_pp_table, - hwmgr->soft_pp_table_size); } memcpy(hwmgr->hardcode_pp_table, buf, size); diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c index a46225c0fc01..1d1875a7cb2d 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c @@ -70,11 +70,12 @@ int psm_set_states(struct pp_eventmgr *eventmgr, unsigned long *state_id) int i; table_entries = hwmgr->num_ps; + state = hwmgr->ps; for (i = 0; i < table_entries; i++) { if (state->id == *state_id) { - hwmgr->request_ps = state; + memcpy(hwmgr->request_ps, state, hwmgr->ps_size); return 0; } state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size); @@ -106,7 +107,7 @@ int psm_adjust_power_state_dynamic(struct pp_eventmgr *eventmgr, bool skip) if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) { phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware); - hwmgr->current_ps = requested; + memcpy(hwmgr->current_ps, hwmgr->request_ps, hwmgr->ps_size); } return 0; } 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, diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index 3f8172f545b0..18f39e89a7aa 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -131,9 +131,6 @@ struct amd_pp_init { struct cgs_device *device; uint32_t chip_family; uint32_t chip_id; - uint32_t rev_id; - uint16_t sub_sys_id; - uint16_t sub_vendor_id; }; enum amd_pp_display_config_type{ diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h index 962cb5385951..d4495839c64c 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h @@ -341,7 +341,6 @@ extern int phm_powerdown_uvd(struct pp_hwmgr *hwmgr); extern int phm_setup_asic(struct pp_hwmgr *hwmgr); extern int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr); extern int phm_disable_dynamic_state_management(struct pp_hwmgr *hwmgr); -extern void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr); extern bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr); extern int phm_block_hw_access(struct pp_hwmgr *hwmgr, bool block); extern int phm_set_power_state(struct pp_hwmgr *hwmgr, diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 36b4ec9c9cb1..e98748344801 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -31,18 +31,20 @@ #include "hwmgr_ppt.h" #include "ppatomctrl.h" #include "hwmgr_ppt.h" +#include "power_state.h" struct pp_instance; struct pp_hwmgr; -struct pp_hw_power_state; -struct pp_power_state; -struct PP_VCEState; struct phm_fan_speed_info; struct pp_atomctrl_voltage_table; - extern int amdgpu_powercontainment; extern int amdgpu_sclk_deep_sleep_en; +extern unsigned amdgpu_pp_feature_mask; + +#define VOLTAGE_SCALE 4 + +uint8_t convert_to_vid(uint16_t vddc); enum DISPLAY_GAP { DISPLAY_GAP_VBLANK_OR_WM = 0, /* Wait for vblank or MCHG watermark. */ @@ -52,7 +54,6 @@ enum DISPLAY_GAP { }; typedef enum DISPLAY_GAP DISPLAY_GAP; - struct vi_dpm_level { bool enabled; uint32_t value; @@ -74,6 +75,19 @@ enum PP_Result { #define PCIE_PERF_REQ_GEN2 3 #define PCIE_PERF_REQ_GEN3 4 +enum PP_FEATURE_MASK { + PP_SCLK_DPM_MASK = 0x1, + PP_MCLK_DPM_MASK = 0x2, + PP_PCIE_DPM_MASK = 0x4, + PP_SCLK_DEEP_SLEEP_MASK = 0x8, + PP_POWER_CONTAINMENT_MASK = 0x10, + PP_UVD_HANDSHAKE_MASK = 0x20, + PP_SMC_VOLTAGE_CONTROL_MASK = 0x40, + PP_VBI_TIME_SUPPORT_MASK = 0x80, + PP_ULV_MASK = 0x100, + PP_ENABLE_GFX_CG_THRU_SMU = 0x200 +}; + enum PHM_BackEnd_Magic { PHM_Dummy_Magic = 0xAA5555AA, PHM_RV770_Magic = 0xDCBAABCD, @@ -354,7 +368,7 @@ struct pp_table_func { int (*pptable_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); }; @@ -573,22 +587,43 @@ struct phm_microcode_version_info { uint32_t NB; }; +#define PP_MAX_VCE_LEVELS 6 + +enum PP_VCE_LEVEL { + PP_VCE_LEVEL_AC_ALL = 0, /* AC, All cases */ + PP_VCE_LEVEL_DC_EE = 1, /* DC, entropy encoding */ + PP_VCE_LEVEL_DC_LL_LOW = 2, /* DC, low latency queue, res <= 720 */ + PP_VCE_LEVEL_DC_LL_HIGH = 3, /* DC, low latency queue, 1080 >= res > 720 */ + PP_VCE_LEVEL_DC_GP_LOW = 4, /* DC, general purpose queue, res <= 720 */ + PP_VCE_LEVEL_DC_GP_HIGH = 5, /* DC, general purpose queue, 1080 >= res > 720 */ +}; + + +enum PP_TABLE_VERSION { + PP_TABLE_V0 = 0, + PP_TABLE_V1, + PP_TABLE_V2, + PP_TABLE_MAX +}; + /** * The main hardware manager structure. */ struct pp_hwmgr { uint32_t chip_family; uint32_t chip_id; - uint32_t hw_revision; - uint32_t sub_sys_id; - uint32_t sub_vendor_id; + uint32_t pp_table_version; void *device; struct pp_smumgr *smumgr; const void *soft_pp_table; uint32_t soft_pp_table_size; void *hardcode_pp_table; bool need_pp_table_upload; + + struct pp_vce_state vce_states[PP_MAX_VCE_LEVELS]; + uint32_t num_vce_state_tables; + enum amd_dpm_forced_level dpm_level; bool block_hw_access; struct phm_gfx_arbiter gfx_arbiter; @@ -626,6 +661,7 @@ struct pp_hwmgr { struct pp_power_state *boot_ps; struct pp_power_state *uvd_ps; struct amd_pp_display_configuration display_config; + uint32_t feature_mask; }; @@ -661,6 +697,8 @@ extern void phm_trim_voltage_table_to_fit_state_table(uint32_t max_vol_steps, st extern int phm_reset_single_dpm_table(void *table, uint32_t count, int max); extern void phm_setup_pcie_table_entry(void *table, uint32_t index, uint32_t pcie_gen, uint32_t pcie_lanes); extern int32_t phm_get_dpm_level_enable_mask_value(void *table); +extern uint8_t phm_get_voltage_id(struct pp_atomctrl_voltage_table *voltage_table, + uint32_t voltage); extern uint8_t phm_get_voltage_index(struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage); extern uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, uint16_t vddci); extern int phm_find_boot_level(void *table, uint32_t value, uint32_t *boot_level); @@ -671,6 +709,9 @@ extern int phm_hwmgr_backend_fini(struct pp_hwmgr *hwmgr); extern uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask); extern void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr); +extern int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, + uint32_t sclk, uint16_t id, uint16_t *voltage); + #define PHM_ENTIRE_REGISTER_MASK 0xFFFFFFFFU #define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT @@ -685,8 +726,6 @@ extern void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr); PHM_FIELD_SHIFT(reg, field)) - - /* Operations on named fields. */ #define PHM_READ_FIELD(device, reg, field) \ diff --git a/drivers/gpu/drm/amd/powerplay/inc/power_state.h b/drivers/gpu/drm/amd/powerplay/inc/power_state.h index a3f0ce4d5835..9ceaed9ac52a 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/power_state.h +++ b/drivers/gpu/drm/amd/powerplay/inc/power_state.h @@ -158,7 +158,7 @@ struct pp_power_state { /*Structure to hold a VCE state entry*/ -struct PP_VCEState { +struct pp_vce_state { uint32_t evclk; uint32_t ecclk; uint32_t sclk; @@ -171,30 +171,28 @@ enum PP_MMProfilingState { PP_MMProfilingState_Stopped }; -struct PP_Clock_Engine_Request { - unsigned long clientType; - unsigned long ctxid; +struct pp_clock_engine_request { + unsigned long client_type; + unsigned long ctx_id; uint64_t context_handle; unsigned long sclk; - unsigned long sclkHardMin; + unsigned long sclk_hard_min; unsigned long mclk; unsigned long iclk; unsigned long evclk; unsigned long ecclk; - unsigned long ecclkHardMin; + unsigned long ecclk_hard_min; unsigned long vclk; unsigned long dclk; - unsigned long samclk; - unsigned long acpclk; - unsigned long sclkOverdrive; - unsigned long mclkOverdrive; + unsigned long sclk_over_drive; + unsigned long mclk_over_drive; unsigned long sclk_threshold; unsigned long flag; unsigned long vclk_ceiling; unsigned long dclk_ceiling; unsigned long num_cus; - unsigned long pmflag; - enum PP_MMProfilingState MMProfilingState; + unsigned long pm_flag; + enum PP_MMProfilingState mm_profiling_state; }; #endif diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h b/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h index d7d83b7c7f95..bfdbec10cdd5 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h +++ b/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h @@ -43,5 +43,8 @@ } while (0) +#define GET_FLEXIBLE_ARRAY_MEMBER_ADDR(type, member, ptr, n) \ + (type *)((char *)&(ptr)->member + (sizeof(type) * (n))) + #endif /* PP_DEBUG_H */ diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h index 3c235f0177cd..34abfd2cde53 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h @@ -74,7 +74,6 @@ struct pp_smumgr_func { struct pp_smumgr { uint32_t chip_family; uint32_t chip_id; - uint32_t hw_revision; void *device; void *backend; uint32_t usec_timeout; @@ -122,6 +121,12 @@ extern int smu_allocate_memory(void *device, uint32_t size, extern int smu_free_memory(void *device, void *handle); +extern int cz_smum_init(struct pp_smumgr *smumgr); +extern int iceland_smum_init(struct pp_smumgr *smumgr); +extern int tonga_smum_init(struct pp_smumgr *smumgr); +extern int fiji_smum_init(struct pp_smumgr *smumgr); +extern int polaris10_smum_init(struct pp_smumgr *smumgr); + #define SMUM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT #define SMUM_FIELD_MASK(reg, field) reg##__##field##_MASK diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c index 87c023e518ab..5a44485526d2 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c @@ -89,13 +89,8 @@ static int cz_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg) if (result != 0) return result; - result = SMUM_WAIT_FIELD_UNEQUAL(smumgr, + return SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMU_MP1_SRBM2P_RESP_0, CONTENT, 0); - - if (result != 0) - return result; - - return 0; } static int cz_set_smc_sram_address(struct pp_smumgr *smumgr, @@ -106,12 +101,12 @@ static int cz_set_smc_sram_address(struct pp_smumgr *smumgr, if (0 != (3 & smc_address)) { printk(KERN_ERR "[ powerplay ] SMC address must be 4 byte aligned\n"); - return -1; + return -EINVAL; } if (limit <= (smc_address + 3)) { printk(KERN_ERR "[ powerplay ] SMC address beyond the SMC RAM area\n"); - return -1; + return -EINVAL; } cgs_write_register(smumgr->device, mmMP0PUB_IND_INDEX_0, @@ -129,9 +124,10 @@ static int cz_write_smc_sram_dword(struct pp_smumgr *smumgr, return -EINVAL; result = cz_set_smc_sram_address(smumgr, smc_address, limit); - cgs_write_register(smumgr->device, mmMP0PUB_IND_DATA_0, value); + if (!result) + cgs_write_register(smumgr->device, mmMP0PUB_IND_DATA_0, value); - return 0; + return result; } static int cz_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr, @@ -148,7 +144,6 @@ static int cz_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr, static int cz_request_smu_load_fw(struct pp_smumgr *smumgr) { struct cz_smumgr *cz_smu = (struct cz_smumgr *)(smumgr->backend); - int result = 0; uint32_t smc_address; if (!smumgr->reload_fw) { @@ -177,11 +172,9 @@ static int cz_request_smu_load_fw(struct pp_smumgr *smumgr) cz_send_msg_to_smc_with_parameter(smumgr, PPSMC_MSG_ExecuteJob, cz_smu->toc_entry_power_profiling_index); - result = cz_send_msg_to_smc_with_parameter(smumgr, + return cz_send_msg_to_smc_with_parameter(smumgr, PPSMC_MSG_ExecuteJob, cz_smu->toc_entry_initialize_index); - - return result; } static int cz_check_fw_load_finish(struct pp_smumgr *smumgr, @@ -195,9 +188,6 @@ static int cz_check_fw_load_finish(struct pp_smumgr *smumgr, if (smumgr == NULL || smumgr->device == NULL) return -EINVAL; - return cgs_read_register(smumgr->device, - mmSMU_MP1_SRBM2P_ARG_0); - cgs_write_register(smumgr->device, mmMP0PUB_IND_INDEX, index); for (i = 0; i < smumgr->usec_timeout; i++) { @@ -275,7 +265,10 @@ static int cz_start_smu(struct pp_smumgr *smumgr) if (smumgr->chip_id == CHIP_STONEY) fw_to_check &= ~(UCODE_ID_SDMA1_MASK | UCODE_ID_CP_MEC_JT2_MASK); - cz_request_smu_load_fw(smumgr); + ret = cz_request_smu_load_fw(smumgr); + if (ret) + printk(KERN_ERR "[ powerplay] SMU firmware load failed\n"); + cz_check_fw_load_finish(smumgr, fw_to_check); ret = cz_load_mec_firmware(smumgr); @@ -566,10 +559,7 @@ static int cz_smu_construct_toc_for_bootup(struct pp_smumgr *smumgr) cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false); - if (smumgr->chip_id == CHIP_STONEY) - cz_smu_populate_single_ucode_load_task(smumgr, - CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false); - else + if (smumgr->chip_id != CHIP_STONEY) cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1, false); cz_smu_populate_single_ucode_load_task(smumgr, @@ -580,10 +570,7 @@ static int cz_smu_construct_toc_for_bootup(struct pp_smumgr *smumgr) CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false); cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); - if (smumgr->chip_id == CHIP_STONEY) - cz_smu_populate_single_ucode_load_task(smumgr, - CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); - else + if (smumgr->chip_id != CHIP_STONEY) cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false); cz_smu_populate_single_ucode_load_task(smumgr, @@ -610,19 +597,12 @@ static int cz_smu_construct_toc(struct pp_smumgr *smumgr) struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend; cz_smu->toc_entry_used_count = 0; - cz_smu_initialize_toc_empty_job_list(smumgr); - cz_smu_construct_toc_for_rlc_aram_save(smumgr); - cz_smu_construct_toc_for_vddgfx_enter(smumgr); - cz_smu_construct_toc_for_vddgfx_exit(smumgr); - cz_smu_construct_toc_for_power_profiling(smumgr); - cz_smu_construct_toc_for_bootup(smumgr); - cz_smu_construct_toc_for_clock_table(smumgr); return 0; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index 704ff4cc0023..8047ad221e74 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -40,7 +40,6 @@ #include "cgs_common.h" #define POLARIS10_SMC_SIZE 0x20000 -#define VOLTAGE_SCALE 4 /* Microcode file is stored in this buffer */ #define BUFFER_SIZE 80000 diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h index e5377aec057f..7c2445f1f043 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h @@ -26,12 +26,27 @@ #include <polaris10_ppsmc.h> #include <pp_endian.h> +#include "smu74.h" struct polaris10_avfs { enum AVFS_BTC_STATUS avfs_btc_status; uint32_t avfs_btc_param; }; +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]; +}; + struct polaris10_buffer_entry { uint32_t data_size; uint32_t mc_addr_low; @@ -40,6 +55,11 @@ struct polaris10_buffer_entry { unsigned long handle; }; +struct polaris10_range_table { + uint32_t trans_lower_frequency; /* in 10khz */ + uint32_t trans_upper_frequency; +}; + struct polaris10_smumgr { uint8_t *header; uint8_t *mec_image; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index cf3cabee8918..bbeb786db003 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c @@ -28,11 +28,7 @@ #include "smumgr.h" #include "cgs_common.h" #include "linux/delay.h" -#include "cz_smumgr.h" -#include "tonga_smumgr.h" -#include "iceland_smumgr.h" -#include "fiji_smumgr.h" -#include "polaris10_smumgr.h" + int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) { @@ -48,7 +44,6 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) smumgr->device = pp_init->device; smumgr->chip_family = pp_init->chip_family; smumgr->chip_id = pp_init->chip_id; - smumgr->hw_revision = pp_init->rev_id; smumgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; smumgr->reload_fw = 1; handle->smu_mgr = smumgr; |