]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/amd/powerplay: add function to store overdrive information for smu11
authorLikun Gao <Likun.Gao@amd.com>
Tue, 8 Jan 2019 06:18:02 +0000 (14:18 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Mar 2019 20:03:59 +0000 (15:03 -0500)
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>
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
drivers/gpu/drm/amd/powerplay/vega20_ppt.c

index e6915ef55b6aec44a3f3bb9d14bbe6ade2b5b34c..dded495374c9b2ae8fc1d3f8170b1ae055cdfcc5 100644 (file)
@@ -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;
index 97d44a668169781c338633fba7e6f09be5c8c599..f2e2baace51725273f0111a609035a3960ce939a 100644 (file)
@@ -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 {
index ed0fbe755bfb76e00b63a485f6d45f616c8465ed..df34953767e2ddd0475578165a533674b85ae78b 100644 (file)
@@ -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)