read vddc range from vbios.

Signed-off-by: Rex Zhu <rex....@amd.com>
---
 drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c | 28 ++++++++++++
 drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h |  3 ++
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 56 ++++++++++++++++--------
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h |  2 +
 4 files changed, 71 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
index 971fb5d..afd7ecf 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
@@ -1505,3 +1505,31 @@ int atomctrl_get_leakage_vddc_base_on_leakage(struct 
pp_hwmgr *hwmgr,
 
        return 0;
 }
+
+void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc,
+                                                       uint32_t *min_vddc)
+{
+       void *profile;
+
+       profile = smu_atom_get_data_table(hwmgr->adev,
+                                       GetIndexIntoMasterTable(DATA, 
ASIC_ProfilingInfo),
+                                       NULL, NULL, NULL);
+
+       if (profile) {
+               switch (hwmgr->chip_id) {
+               case CHIP_TONGA:
+               case CHIP_FIJI:
+                       *max_vddc = ((ATOM_ASIC_PROFILING_INFO_V3_3 
*)profile)->ulMaxVddc/4;
+                       *min_vddc = ((ATOM_ASIC_PROFILING_INFO_V3_3 
*)profile)->ulMinVddc/4;
+                       break;
+               case CHIP_POLARIS11:
+               case CHIP_POLARIS10:
+               case CHIP_POLARIS12:
+                       *max_vddc = ((ATOM_ASIC_PROFILING_INFO_V3_6 
*)profile)->ulMaxVddc/100;
+                       *min_vddc = ((ATOM_ASIC_PROFILING_INFO_V3_6 
*)profile)->ulMinVddc/100;
+                       break;
+               default:
+                       return;
+               }
+       }
+}
\ No newline at end of file
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h 
b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
index c672a50..e1b5d6b 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
@@ -320,5 +320,8 @@ extern int atomctrl_get_leakage_vddc_base_on_leakage(struct 
pp_hwmgr *hwmgr,
                                        uint16_t virtual_voltage_id,
                                        uint16_t efuse_voltage_id);
 extern int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t 
*virtual_voltage_id);
+
+extern void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t 
*max_vddc,
+                                                       uint32_t *min_vddc);
 #endif
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 9654593..966b5b1 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -838,6 +838,33 @@ static int smu7_odn_initial_default_setting(struct 
pp_hwmgr *hwmgr)
        return 0;
 }
 
+static void smu7_setup_voltage_range_from_vbios(struct pp_hwmgr *hwmgr)
+{
+       struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+       struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
+       struct phm_ppt_v1_information *table_info =
+                       (struct phm_ppt_v1_information *)(hwmgr->pptable);
+       uint32_t min_vddc, max_vddc;
+
+       if (table_info == NULL)
+               return;
+
+       dep_sclk_table = table_info->vdd_dep_on_sclk;
+
+       atomctrl_get_voltage_range(hwmgr, &max_vddc, &min_vddc);
+
+       if (min_vddc == 0 || min_vddc > 2000
+               || min_vddc > dep_sclk_table->entries[0].vddc)
+               min_vddc = dep_sclk_table->entries[0].vddc;
+
+       if (max_vddc == 0 || max_vddc > 2000
+               || max_vddc < dep_sclk_table->entries[dep_sclk_table->count - 
1].vddc)
+               max_vddc = dep_sclk_table->entries[dep_sclk_table->count - 
1].vddc;
+
+       data->odn_dpm_table.min_vddc = min_vddc;
+       data->odn_dpm_table.max_vddc = max_vddc;
+}
+
 static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
 {
        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
@@ -856,8 +883,10 @@ static int smu7_setup_default_dpm_tables(struct pp_hwmgr 
*hwmgr)
                        sizeof(struct smu7_dpm_table));
 
        /* initialize ODN table */
-       if (hwmgr->od_enabled)
+       if (hwmgr->od_enabled) {
+               smu7_setup_voltage_range_from_vbios(hwmgr);
                smu7_odn_initial_default_setting(hwmgr);
+       }
 
        return 0;
 }
@@ -4605,35 +4634,26 @@ static bool smu7_check_clk_voltage_valid(struct 
pp_hwmgr *hwmgr,
 {
        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 
-       struct phm_ppt_v1_information *table_info =
-                       (struct phm_ppt_v1_information *)(hwmgr->pptable);
-       uint32_t min_vddc;
-       struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
-
-       if (table_info == NULL)
-               return false;
-
-       dep_sclk_table = table_info->vdd_dep_on_sclk;
-       min_vddc = dep_sclk_table->entries[0].vddc;
-
-       if (voltage < min_vddc || voltage > 2000) {
-               pr_info("OD voltage is out of range [%d - 2000] mV\n", 
min_vddc);
+       if (voltage < data->odn_dpm_table.min_vddc || voltage > 
data->odn_dpm_table.max_vddc) {
+               pr_info("OD voltage is out of range [%d - %d] mV\n",
+                                               data->odn_dpm_table.min_vddc,
+                                               data->odn_dpm_table.max_vddc);
                return false;
        }
 
        if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
-               if (data->vbios_boot_state.sclk_bootup_value > clk ||
+               if (data->golden_dpm_table.sclk_table.dpm_levels[0].value > clk 
||
                        hwmgr->platform_descriptor.overdriveLimit.engineClock < 
clk) {
                        pr_info("OD engine clock is out of range [%d - %d] 
MHz\n",
-                               data->vbios_boot_state.sclk_bootup_value,
+                               
data->golden_dpm_table.sclk_table.dpm_levels[0].value / 100,
                                
hwmgr->platform_descriptor.overdriveLimit.engineClock / 100);
                        return false;
                }
        } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
-               if (data->vbios_boot_state.mclk_bootup_value > clk ||
+               if (data->golden_dpm_table.mclk_table.dpm_levels[0].value > clk 
||
                        hwmgr->platform_descriptor.overdriveLimit.memoryClock < 
clk) {
                        pr_info("OD memory clock is out of range [%d - %d] 
MHz\n",
-                               data->vbios_boot_state.mclk_bootup_value/100,
+                               
data->golden_dpm_table.mclk_table.dpm_levels[0].value / 100,
                                
hwmgr->platform_descriptor.overdriveLimit.memoryClock / 100);
                        return false;
                }
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h 
b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h
index f40179c..51a776e 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h
@@ -184,6 +184,8 @@ struct smu7_odn_dpm_table {
        struct smu7_odn_clock_voltage_dependency_table  vdd_dependency_on_sclk;
        struct smu7_odn_clock_voltage_dependency_table  vdd_dependency_on_mclk;
        uint32_t                                        odn_mclk_min_limit;
+       uint32_t min_vddc;
+       uint32_t max_vddc;
 };
 
 struct profile_mode_setting {
-- 
1.9.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to