drm/amd/powerplay: add function to set default overdrive settings
authorLikun Gao <Likun.Gao@amd.com>
Wed, 9 Jan 2019 11:11:58 +0000 (19:11 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Mar 2019 20:03:59 +0000 (15:03 -0500)
Add function of vega20_set_default_od8_setttings for vega20 with smu11
arch to setup default overdrive value.

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/smu_v11_0.c
drivers/gpu/drm/amd/powerplay/vega20_ppt.c
drivers/gpu/drm/amd/powerplay/vega20_ppt.h

index dded495374c9b2ae8fc1d3f8170b1ae055cdfcc5..04ee523b2bf90be32d2c29128e09f5aee07d1ef5 100644 (file)
@@ -533,6 +533,10 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
        if (ret)
                return ret;
 
+       ret = smu_set_od8_default_settings(smu);
+       if (ret)
+               return ret;
+
        ret = smu_populate_umd_state_clk(smu);
        if (ret)
                return ret;
@@ -704,6 +708,16 @@ static int smu_hw_fini(void *handle)
                table_context->od_settings_min = NULL;
        }
 
+       if (table_context->overdrive_table) {
+               kfree(table_context->overdrive_table);
+               table_context->overdrive_table = NULL;
+       }
+
+       if (table_context->od8_settings) {
+               kfree(table_context->od8_settings);
+               table_context->od8_settings = NULL;
+       }
+
        ret = smu_fini_fb_allocations(smu);
        if (ret)
                return ret;
index f2e2baace51725273f0111a609035a3960ce939a..635c8b8e6d8d7b2d4fc4908a9f8483cd759d96bd 100644 (file)
@@ -196,6 +196,8 @@ struct smu_table_context
        uint8_t                         *od_feature_capabilities;
        uint32_t                        *od_settings_max;
        uint32_t                        *od_settings_min;
+       void                            *overdrive_table;
+       void                            *od8_settings;
 };
 
 struct smu_dpm_context {
@@ -258,6 +260,7 @@ struct pptable_funcs {
        int (*populate_umd_state_clk)(struct smu_context *smu);
        int (*print_clk_levels)(struct smu_context *smu, enum pp_clock_type type, char *buf);
        int (*force_clk_levels)(struct smu_context *smu, enum pp_clock_type type, uint32_t mask);
+       int (*set_default_od8_settings)(struct smu_context *smu);
        int (*get_clock_by_type_with_latency)(struct smu_context *smu,
                                              enum amd_pp_clock_type type,
                                              struct
@@ -331,6 +334,7 @@ struct smu_funcs
        int (*notify_smu_enable_pwe)(struct smu_context *smu);
        int (*set_watermarks_for_clock_ranges)(struct smu_context *smu,
                                               struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
+       int (*set_od8_default_settings)(struct smu_context *smu);
 };
 
 #define smu_init_microcode(smu) \
@@ -377,6 +381,8 @@ struct smu_funcs
        ((smu)->funcs->system_features_control ? (smu)->funcs->system_features_control((smu), (en)) : 0)
 #define smu_init_max_sustainable_clocks(smu) \
        ((smu)->funcs->init_max_sustainable_clocks ? (smu)->funcs->init_max_sustainable_clocks((smu)) : 0)
+#define smu_set_od8_default_settings(smu) \
+       ((smu)->funcs->set_od8_default_settings ? (smu)->funcs->set_od8_default_settings((smu)) : 0)
 #define smu_send_smc_msg(smu, msg) \
        ((smu)->funcs->send_smc_msg? (smu)->funcs->send_smc_msg((smu), (msg)) : 0)
 #define smu_send_smc_msg_with_param(smu, msg, param) \
@@ -407,6 +413,8 @@ struct smu_funcs
        ((smu)->ppt_funcs->set_default_dpm_table ? (smu)->ppt_funcs->set_default_dpm_table((smu)) : 0)
 #define smu_populate_umd_state_clk(smu) \
        ((smu)->ppt_funcs->populate_umd_state_clk ? (smu)->ppt_funcs->populate_umd_state_clk((smu)) : 0)
+#define smu_set_default_od8_settings(smu) \
+       ((smu)->ppt_funcs->set_default_od8_settings ? (smu)->ppt_funcs->set_default_od8_settings((smu)) : 0)
 #define smu_get_power_limit(smu) \
        ((smu)->funcs->get_power_limit? (smu)->funcs->get_power_limit((smu)) : 0)
 #define smu_get_current_clk_freq(smu, clk_id, value) \
index e455ed4e09a84c271b30d479371940190ba6bfa7..037d900c450cce545536f39bfee7f4636dee15a5 100644 (file)
@@ -542,61 +542,12 @@ static int smu_v11_0_populate_smc_pptable(struct smu_context *smu)
        return ret;
 }
 
-static int smu_v11_0_copy_table_to_smc(struct smu_context *smu,
-                                      uint32_t table_id)
-{
-       struct smu_table_context *table_context = &smu->smu_table;
-       struct smu_table *driver_pptable = &smu->smu_table.tables[table_id];
-       int ret = 0;
-
-       if (table_id >= TABLE_COUNT) {
-               pr_err("Invalid SMU Table ID for smu11!");
-               return -EINVAL;
-       }
-
-       if (!driver_pptable->cpu_addr) {
-               pr_err("Invalid virtual address for smu11!");
-               return -EINVAL;
-       }
-       if (!driver_pptable->mc_address) {
-               pr_err("Invalid MC address for smu11!");
-               return -EINVAL;
-       }
-       if (!driver_pptable->size) {
-               pr_err("Invalid SMU Table size for smu11!");
-               return -EINVAL;
-       }
-
-       memcpy(driver_pptable->cpu_addr, table_context->driver_pptable,
-              driver_pptable->size);
-
-       ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrHigh,
-                       upper_32_bits(driver_pptable->mc_address));
-       if (ret) {
-               pr_err("[CopyTableToSMC] Attempt to Set Dram Addr High Failed!");
-               return ret;
-       }
-       ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrLow,
-                       lower_32_bits(driver_pptable->mc_address));
-       if (ret) {
-               pr_err("[CopyTableToSMC] Attempt to Set Dram Addr Low Failed!");
-               return ret;
-       }
-       ret = smu_send_smc_msg_with_param(smu, SMU_MSG_TransferTableDram2Smu,
-                                         table_id);
-       if (ret) {
-               pr_err("[CopyTableToSMC] Attempt to Transfer Table To SMU Failed!");
-               return ret;
-       }
-
-       return 0;
-}
-
 static int smu_v11_0_write_pptable(struct smu_context *smu)
 {
+       struct smu_table_context *table_context = &smu->smu_table;
        int ret = 0;
 
-       ret = smu_v11_0_copy_table_to_smc(smu, TABLE_PPTABLE);
+       ret = smu_update_table(smu, TABLE_PPTABLE, table_context->driver_pptable, true);
 
        return ret;
 }
@@ -1246,6 +1197,36 @@ smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct
        return ret;
 }
 
+static int smu_v11_0_set_od8_default_settings(struct smu_context *smu)
+{
+       struct smu_table_context *table_context = &smu->smu_table;
+       int ret;
+
+       if (table_context->overdrive_table)
+                return -EINVAL;
+
+       table_context->overdrive_table = kzalloc(sizeof(OverDriveTable_t), GFP_KERNEL);
+
+       if (!table_context->overdrive_table)
+               return -ENOMEM;
+
+       ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, false);
+       if (ret) {
+               pr_err("Failed to export over drive table!\n");
+               return ret;
+       }
+
+       smu_set_default_od8_settings(smu);
+
+       ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, true);
+       if (ret) {
+               pr_err("Failed to import over drive table!\n");
+               return ret;
+       }
+
+       return 0;
+}
+
 static const struct smu_funcs smu_v11_0_funcs = {
        .init_microcode = smu_v11_0_init_microcode,
        .load_microcode = smu_v11_0_load_microcode,
@@ -1282,6 +1263,7 @@ static const struct smu_funcs smu_v11_0_funcs = {
        .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
        .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
        .set_watermarks_for_clock_ranges = smu_v11_0_set_watermarks_for_clock_ranges,
+       .set_od8_default_settings = smu_v11_0_set_od8_default_settings,
 };
 
 void smu_v11_0_set_smu_funcs(struct smu_context *smu)
index df34953767e2ddd0475578165a533674b85ae78b..c398899320d1333e09ffaa2f3793521830a6bfdf 100644 (file)
@@ -904,6 +904,208 @@ static int vega20_get_clock_by_type_with_latency(struct smu_context *smu,
        return ret;
 }
 
+static int vega20_overdrive_get_gfx_clk_base_voltage(struct smu_context *smu,
+                                                    uint32_t *voltage,
+                                                    uint32_t freq)
+{
+       int ret;
+
+       ret = smu_send_smc_msg_with_param(smu,
+                       SMU_MSG_GetAVFSVoltageByDpm,
+                       ((AVFS_CURVE << 24) | (OD8_HOTCURVE_TEMPERATURE << 16) | freq));
+       if (ret) {
+               pr_err("[GetBaseVoltage] failed to get GFXCLK AVFS voltage from SMU!");
+               return ret;
+       }
+
+       smu_read_smc_arg(smu, voltage);
+       *voltage = *voltage / VOLTAGE_SCALE;
+
+       return 0;
+}
+
+static int vega20_set_default_od8_setttings(struct smu_context *smu)
+{
+       struct smu_table_context *table_context = &smu->smu_table;
+       OverDriveTable_t *od_table = (OverDriveTable_t *)(table_context->overdrive_table);
+       struct vega20_od8_settings *od8_settings = NULL;
+       PPTable_t *smc_pptable = table_context->driver_pptable;
+       int i, ret;
+
+       if (table_context->od8_settings)
+               return -EINVAL;
+
+       table_context->od8_settings = kzalloc(sizeof(struct vega20_od8_settings), GFP_KERNEL);
+
+       if (!table_context->od8_settings)
+               return -ENOMEM;
+
+       memset(table_context->od8_settings, 0, sizeof(struct vega20_od8_settings));
+       od8_settings = (struct vega20_od8_settings *)table_context->od8_settings;
+
+       if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
+               if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_GFXCLK_LIMITS] &&
+                   table_context->od_settings_max[OD8_SETTING_GFXCLK_FMAX] > 0 &&
+                   table_context->od_settings_min[OD8_SETTING_GFXCLK_FMIN] > 0 &&
+                   (table_context->od_settings_max[OD8_SETTING_GFXCLK_FMAX] >=
+                    table_context->od_settings_min[OD8_SETTING_GFXCLK_FMIN])) {
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].feature_id =
+                               OD8_GFXCLK_LIMITS;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].feature_id =
+                               OD8_GFXCLK_LIMITS;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].default_value =
+                               od_table->GfxclkFmin;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].default_value =
+                               od_table->GfxclkFmax;
+               }
+
+               if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_GFXCLK_CURVE] &&
+                   (table_context->od_settings_min[OD8_SETTING_GFXCLK_VOLTAGE1] >=
+                    smc_pptable->MinVoltageGfx / VOLTAGE_SCALE) &&
+                   (table_context->od_settings_max[OD8_SETTING_GFXCLK_VOLTAGE3] <=
+                    smc_pptable->MaxVoltageGfx / VOLTAGE_SCALE) &&
+                   (table_context->od_settings_min[OD8_SETTING_GFXCLK_VOLTAGE1] <=
+                    table_context->od_settings_max[OD8_SETTING_GFXCLK_VOLTAGE3])) {
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].feature_id =
+                               OD8_GFXCLK_CURVE;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id =
+                               OD8_GFXCLK_CURVE;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].feature_id =
+                               OD8_GFXCLK_CURVE;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id =
+                               OD8_GFXCLK_CURVE;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].feature_id =
+                               OD8_GFXCLK_CURVE;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id =
+                               OD8_GFXCLK_CURVE;
+
+                       od_table->GfxclkFreq1 = od_table->GfxclkFmin;
+                       od_table->GfxclkFreq2 = (od_table->GfxclkFmin + od_table->GfxclkFmax) / 2;
+                       od_table->GfxclkFreq3 = od_table->GfxclkFmax;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].default_value =
+                               od_table->GfxclkFreq1;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].default_value =
+                               od_table->GfxclkFreq2;
+                       od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].default_value =
+                               od_table->GfxclkFreq3;
+
+                       ret = vega20_overdrive_get_gfx_clk_base_voltage(smu,
+                               &od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value,
+                               od_table->GfxclkFreq1);
+                       if (ret)
+                               od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value = 0;
+                       od_table->GfxclkVolt1 =
+                               od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value
+                               * VOLTAGE_SCALE;
+                       ret = vega20_overdrive_get_gfx_clk_base_voltage(smu,
+                               &od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value,
+                               od_table->GfxclkFreq2);
+                       if (ret)
+                               od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value = 0;
+                       od_table->GfxclkVolt2 =
+                               od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value
+                               * VOLTAGE_SCALE;
+                       ret = vega20_overdrive_get_gfx_clk_base_voltage(smu,
+                               &od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value,
+                               od_table->GfxclkFreq3);
+                       if (ret)
+                               od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value = 0;
+                       od_table->GfxclkVolt3 =
+                               od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value
+                               * VOLTAGE_SCALE;
+               }
+       }
+
+       if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
+               if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_UCLK_MAX] &&
+                   table_context->od_settings_min[OD8_SETTING_UCLK_FMAX] > 0 &&
+                   table_context->od_settings_max[OD8_SETTING_UCLK_FMAX] > 0 &&
+                   (table_context->od_settings_max[OD8_SETTING_UCLK_FMAX] >=
+                    table_context->od_settings_min[OD8_SETTING_UCLK_FMAX])) {
+                       od8_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].feature_id =
+                               OD8_UCLK_MAX;
+                       od8_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].default_value =
+                               od_table->UclkFmax;
+               }
+       }
+
+       if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_POWER_LIMIT] &&
+           table_context->od_settings_min[OD8_SETTING_POWER_PERCENTAGE] > 0 &&
+           table_context->od_settings_min[OD8_SETTING_POWER_PERCENTAGE] <= 100 &&
+           table_context->od_settings_max[OD8_SETTING_POWER_PERCENTAGE] > 0 &&
+           table_context->od_settings_max[OD8_SETTING_POWER_PERCENTAGE] <= 100) {
+               od8_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].feature_id =
+                       OD8_POWER_LIMIT;
+               od8_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].default_value =
+                       od_table->OverDrivePct;
+       }
+
+       if (smu_feature_is_enabled(smu, FEATURE_FAN_CONTROL_BIT)) {
+               if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_FAN_ACOUSTIC_LIMIT] &&
+                   table_context->od_settings_min[OD8_SETTING_FAN_ACOUSTIC_LIMIT] > 0 &&
+                   table_context->od_settings_max[OD8_SETTING_FAN_ACOUSTIC_LIMIT] > 0 &&
+                   (table_context->od_settings_max[OD8_SETTING_FAN_ACOUSTIC_LIMIT] >=
+                    table_context->od_settings_min[OD8_SETTING_FAN_ACOUSTIC_LIMIT])) {
+                       od8_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].feature_id =
+                               OD8_ACOUSTIC_LIMIT_SCLK;
+                       od8_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].default_value =
+                               od_table->FanMaximumRpm;
+               }
+
+               if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_FAN_SPEED_MIN] &&
+                   table_context->od_settings_min[OD8_SETTING_FAN_MIN_SPEED] > 0 &&
+                   table_context->od_settings_max[OD8_SETTING_FAN_MIN_SPEED] > 0 &&
+                   (table_context->od_settings_max[OD8_SETTING_FAN_MIN_SPEED] >=
+                    table_context->od_settings_min[OD8_SETTING_FAN_MIN_SPEED])) {
+                       od8_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].feature_id =
+                               OD8_FAN_SPEED_MIN;
+                       od8_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].default_value =
+                               od_table->FanMinimumPwm * smc_pptable->FanMaximumRpm / 100;
+               }
+       }
+
+       if (smu_feature_is_enabled(smu, FEATURE_THERMAL_BIT)) {
+               if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_TEMPERATURE_FAN] &&
+                   table_context->od_settings_min[OD8_SETTING_FAN_TARGET_TEMP] > 0 &&
+                   table_context->od_settings_max[OD8_SETTING_FAN_TARGET_TEMP] > 0 &&
+                   (table_context->od_settings_max[OD8_SETTING_FAN_TARGET_TEMP] >=
+                    table_context->od_settings_min[OD8_SETTING_FAN_TARGET_TEMP])) {
+                       od8_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].feature_id =
+                               OD8_TEMPERATURE_FAN;
+                       od8_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].default_value =
+                               od_table->FanTargetTemperature;
+               }
+
+               if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_TEMPERATURE_SYSTEM] &&
+                   table_context->od_settings_min[OD8_SETTING_OPERATING_TEMP_MAX] > 0 &&
+                   table_context->od_settings_max[OD8_SETTING_OPERATING_TEMP_MAX] > 0 &&
+                   (table_context->od_settings_max[OD8_SETTING_OPERATING_TEMP_MAX] >=
+                    table_context->od_settings_min[OD8_SETTING_OPERATING_TEMP_MAX])) {
+                       od8_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].feature_id =
+                               OD8_TEMPERATURE_SYSTEM;
+                       od8_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].default_value =
+                               od_table->MaxOpTemp;
+               }
+       }
+
+       for (i = 0; i < OD8_SETTING_COUNT; i++) {
+               if (od8_settings->od8_settings_array[i].feature_id) {
+                       od8_settings->od8_settings_array[i].min_value =
+                               table_context->od_settings_min[i];
+                       od8_settings->od8_settings_array[i].max_value =
+                               table_context->od_settings_max[i];
+                       od8_settings->od8_settings_array[i].current_value =
+                               od8_settings->od8_settings_array[i].default_value;
+               } else {
+                       od8_settings->od8_settings_array[i].min_value = 0;
+                       od8_settings->od8_settings_array[i].max_value = 0;
+                       od8_settings->od8_settings_array[i].current_value = 0;
+               }
+       }
+
+       return 0;
+}
+
 static const struct pptable_funcs vega20_ppt_funcs = {
        .alloc_dpm_context = vega20_allocate_dpm_context,
        .store_powerplay_table = vega20_store_powerplay_table,
@@ -917,6 +1119,7 @@ static const struct pptable_funcs vega20_ppt_funcs = {
        .print_clk_levels = vega20_print_clk_levels,
        .force_clk_levels = vega20_force_clk_levels,
        .get_clock_by_type_with_latency = vega20_get_clock_by_type_with_latency,
+       .set_default_od8_settings = vega20_set_default_od8_setttings,
 };
 
 void vega20_set_ppt_funcs(struct smu_context *smu)
index ceba4f7dbab4a8839ea22561163c7d7b8e233c1e..9b229b2f09f5783f64a6fb3e06b1b27d042682a2 100644 (file)
 #define MAX_REGULAR_DPM_NUMBER 16
 #define MAX_PCIE_CONF 2
 
+#define VOLTAGE_SCALE 4
+#define AVFS_CURVE 0
+#define OD8_HOTCURVE_TEMPERATURE 85
+
 struct vega20_dpm_level {
         bool            enabled;
         uint32_t        value;
@@ -70,6 +74,53 @@ struct vega20_dpm_table {
         struct vega20_pcie_table        pcie_table;
 };
 
+enum OD8_FEATURE_ID
+{
+       OD8_GFXCLK_LIMITS               = 1 << 0,
+       OD8_GFXCLK_CURVE                = 1 << 1,
+       OD8_UCLK_MAX                    = 1 << 2,
+       OD8_POWER_LIMIT                 = 1 << 3,
+       OD8_ACOUSTIC_LIMIT_SCLK         = 1 << 4,   //FanMaximumRpm
+       OD8_FAN_SPEED_MIN               = 1 << 5,   //FanMinimumPwm
+       OD8_TEMPERATURE_FAN             = 1 << 6,   //FanTargetTemperature
+       OD8_TEMPERATURE_SYSTEM          = 1 << 7,   //MaxOpTemp
+       OD8_MEMORY_TIMING_TUNE          = 1 << 8,
+       OD8_FAN_ZERO_RPM_CONTROL        = 1 << 9
+};
+
+enum OD8_SETTING_ID
+{
+       OD8_SETTING_GFXCLK_FMIN = 0,
+       OD8_SETTING_GFXCLK_FMAX,
+       OD8_SETTING_GFXCLK_FREQ1,
+       OD8_SETTING_GFXCLK_VOLTAGE1,
+       OD8_SETTING_GFXCLK_FREQ2,
+       OD8_SETTING_GFXCLK_VOLTAGE2,
+       OD8_SETTING_GFXCLK_FREQ3,
+       OD8_SETTING_GFXCLK_VOLTAGE3,
+       OD8_SETTING_UCLK_FMAX,
+       OD8_SETTING_POWER_PERCENTAGE,
+       OD8_SETTING_FAN_ACOUSTIC_LIMIT,
+       OD8_SETTING_FAN_MIN_SPEED,
+       OD8_SETTING_FAN_TARGET_TEMP,
+       OD8_SETTING_OPERATING_TEMP_MAX,
+       OD8_SETTING_AC_TIMING,
+       OD8_SETTING_FAN_ZERO_RPM_CONTROL,
+       OD8_SETTING_COUNT
+};
+
+struct vega20_od8_single_setting {
+       uint32_t        feature_id;
+       int32_t         min_value;
+       int32_t         max_value;
+       int32_t         current_value;
+       int32_t         default_value;
+};
+
+struct vega20_od8_settings {
+       struct vega20_od8_single_setting        od8_settings_array[OD8_SETTING_COUNT];
+};
+
 extern void vega20_set_ppt_funcs(struct smu_context *smu);
 
 #endif