From b55ca3bdaf0bbfd14ad6619a991fbd324ae1ad4b Mon Sep 17 00:00:00 2001 From: Likun Gao Date: Tue, 8 Jan 2019 14:18:02 +0800 Subject: [PATCH] drm/amd/powerplay: add function to store overdrive information for smu11 Add vega20_setup_od8_information function to store overdrive information from powerplay_table to smu_table which will used when setting od8. Signed-off-by: Likun Gao Reviewed-by: Kevin Wang Reviewed-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 15 ++++ .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 4 + drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 86 ++++++++++++++++++- 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index e6915ef55b6a..dded495374c9 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -689,6 +689,21 @@ static int smu_hw_fini(void *handle) table_context->max_sustainable_clocks = NULL; } + if (table_context->od_feature_capabilities) { + kfree(table_context->od_feature_capabilities); + table_context->od_feature_capabilities = NULL; + } + + if (table_context->od_settings_max) { + kfree(table_context->od_settings_max); + table_context->od_settings_max = NULL; + } + + if (table_context->od_settings_min) { + kfree(table_context->od_settings_min); + table_context->od_settings_min = NULL; + } + ret = smu_fini_fb_allocations(smu); if (ret) return ret; diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index 97d44a668169..f2e2baace517 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -192,6 +192,10 @@ struct smu_table_context struct smu_table memory_pool; uint16_t software_shutdown_temp; uint8_t thermal_controller_type; + + uint8_t *od_feature_capabilities; + uint32_t *od_settings_max; + uint32_t *od_settings_min; }; struct smu_dpm_context { diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c index ed0fbe755bfb..df34953767e2 100644 --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c @@ -146,10 +146,92 @@ static int vega20_allocate_dpm_context(struct smu_context *smu) return 0; } +static int vega20_setup_od8_information(struct smu_context *smu) +{ + ATOM_Vega20_POWERPLAYTABLE *powerplay_table = NULL; + struct smu_table_context *table_context = &smu->smu_table; + + uint32_t od_feature_count, od_feature_array_size, + od_setting_count, od_setting_array_size; + + if (!table_context->power_play_table) + return -EINVAL; + + powerplay_table = table_context->power_play_table; + + if (powerplay_table->OverDrive8Table.ucODTableRevision == 1) { + /* Setup correct ODFeatureCount, and store ODFeatureArray from + * powerplay table to od_feature_capabilities */ + od_feature_count = + (le32_to_cpu(powerplay_table->OverDrive8Table.ODFeatureCount) > + ATOM_VEGA20_ODFEATURE_COUNT) ? + ATOM_VEGA20_ODFEATURE_COUNT : + le32_to_cpu(powerplay_table->OverDrive8Table.ODFeatureCount); + + od_feature_array_size = sizeof(uint8_t) * od_feature_count; + + if (table_context->od_feature_capabilities) + return -EINVAL; + + table_context->od_feature_capabilities = kzalloc(od_feature_array_size, GFP_KERNEL); + if (!table_context->od_feature_capabilities) + return -ENOMEM; + + memcpy(table_context->od_feature_capabilities, + &powerplay_table->OverDrive8Table.ODFeatureCapabilities, + od_feature_array_size); + + /* Setup correct ODSettingCount, and store ODSettingArray from + * powerplay table to od_settings_max and od_setting_min */ + od_setting_count = + (le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingCount) > + ATOM_VEGA20_ODSETTING_COUNT) ? + ATOM_VEGA20_ODSETTING_COUNT : + le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingCount); + + od_setting_array_size = sizeof(uint32_t) * od_setting_count; + + if (table_context->od_settings_max) + return -EINVAL; + + table_context->od_settings_max = kzalloc(od_setting_array_size, GFP_KERNEL); + + if (!table_context->od_settings_max) { + kfree(table_context->od_feature_capabilities); + table_context->od_feature_capabilities = NULL; + return -ENOMEM; + } + + memcpy(table_context->od_settings_max, + &powerplay_table->OverDrive8Table.ODSettingsMax, + od_setting_array_size); + + if (table_context->od_settings_min) + return -EINVAL; + + table_context->od_settings_min = kzalloc(od_setting_array_size, GFP_KERNEL); + + if (!table_context->od_settings_min) { + kfree(table_context->od_feature_capabilities); + table_context->od_feature_capabilities = NULL; + kfree(table_context->od_settings_max); + table_context->od_settings_max = NULL; + return -ENOMEM; + } + + memcpy(table_context->od_settings_min, + &powerplay_table->OverDrive8Table.ODSettingsMin, + od_setting_array_size); + } + + return 0; +} + static int vega20_store_powerplay_table(struct smu_context *smu) { ATOM_Vega20_POWERPLAYTABLE *powerplay_table = NULL; struct smu_table_context *table_context = &smu->smu_table; + int ret; if (!table_context->power_play_table) return -EINVAL; @@ -162,7 +244,9 @@ static int vega20_store_powerplay_table(struct smu_context *smu) table_context->software_shutdown_temp = powerplay_table->usSoftwareShutdownTemp; table_context->thermal_controller_type = powerplay_table->ucThermalControllerType; - return 0; + ret = vega20_setup_od8_information(smu); + + return ret; } static int vega20_append_powerplay_table(struct smu_context *smu) -- 2.30.2