aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLikun Gao <Likun.Gao@amd.com>2019-01-08 14:18:02 +0800
committerAlex Deucher <alexander.deucher@amd.com>2019-03-19 15:03:59 -0500
commitb55ca3bdaf0bbfd14ad6619a991fbd324ae1ad4b (patch)
tree9da4728c2601b1cc76f258dcc38d21b1d4b47507 /drivers/gpu
parentdrm/amd/powerplay: implement interface to set watermarks for clock ranges (diff)
downloadlinux-b55ca3bdaf0bbfd14ad6619a991fbd324ae1ad4b.tar.gz
linux-b55ca3bdaf0bbfd14ad6619a991fbd324ae1ad4b.zip
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 <Likun.Gao@amd.com> Reviewed-by: Kevin Wang <kevin1.wang@amd.com> Reviewed-by: Evan Quan <evan.quan@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/powerplay/amdgpu_smu.c15
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h4
-rw-r--r--drivers/gpu/drm/amd/powerplay/vega20_ppt.c86
3 files changed, 104 insertions, 1 deletions
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)