Change-Id: Ifd9693470534d96bfa99a6de2fa79c84d6b97662
Signed-off-by: Rex Zhu <rex....@amd.com>
---
 drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c        |  52 +++++----
 drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c   |  84 +++++++++++++-
 drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h   |   8 +-
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c   | 124 ++++++++++++++++-----
 .../gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c   |   6 +-
 5 files changed, 215 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
index f36820d..1d27cbd 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
@@ -44,6 +44,7 @@
 static int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 static int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 static int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr);
+static int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr);
 
 uint8_t convert_to_vid(uint16_t vddc)
 {
@@ -76,6 +77,13 @@ int hwmgr_early_init(struct pp_instance *handle)
        hwmgr->fan_ctrl_is_in_default_mode = true;
 
        switch (hwmgr->chip_family) {
+       case AMDGPU_FAMILY_CI:
+               ci_set_asic_special_caps(hwmgr);
+               hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
+                                       PP_ENABLE_GFX_CG_THRU_SMU);
+               hwmgr->pp_table_version = PP_TABLE_V0;
+               smu7_init_function_pointers(hwmgr);
+               break;
        case AMDGPU_FAMILY_CZ:
                cz_init_function_pointers(hwmgr);
                break;
@@ -748,28 +756,8 @@ void phm_apply_dal_min_voltage_request(struct pp_hwmgr 
*hwmgr)
 
 void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr)
 {
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableVoltageTransition);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableEngineTransition);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableMemoryTransition);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableMGClockGating);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableMGCGTSSM);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableLSClockGating);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_Force3DClockSupport);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableLightSleep);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableMCLS);
-       phm_cap_set(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisablePowerGating);
-
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableDPM);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_DisableSMUUVDHandshake);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_ThermalAutoThrottling);
-
        phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_PCIEPerformanceRequest);
 
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_NoOD5Support);
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_UserMaxClockForMultiDisplays);
-
-       phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_VpuRecoveryInProgress);
-
        phm_cap_set(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_UVDDPM);
        phm_cap_set(hwmgr->platform_descriptor.platformCaps, 
PHM_PlatformCaps_VCEDPM);
 
@@ -794,7 +782,8 @@ void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr)
 
        phm_cap_set(hwmgr->platform_descriptor.platformCaps,
                                                
PHM_PlatformCaps_FanSpeedInTableIsRPM);
-
+       phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+                                               PHM_PlatformCaps_EVV);
        return;
 }
 
@@ -877,7 +866,6 @@ int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr)
                        PHM_PlatformCaps_TDRamping);
        phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_TCPRamping);
-
        return 0;
 }
 
@@ -896,7 +884,6 @@ int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr)
                      PHM_PlatformCaps_UVDPowerGating);
        phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
                      PHM_PlatformCaps_VCEPowerGating);
-
        return 0;
 }
 
@@ -910,7 +897,24 @@ int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr)
                        PHM_PlatformCaps_TDRamping);
        phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_TCPRamping);
+       return 0;
+}
+
+int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr)
+{
+       phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+                                               PHM_PlatformCaps_EVV);
+       phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+                       PHM_PlatformCaps_SQRamping);
+       phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+                       PHM_PlatformCaps_DBRamping);
+       phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+                       PHM_PlatformCaps_TDRamping);
+       phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+                       PHM_PlatformCaps_TCPRamping);
+       phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+                       PHM_PlatformCaps_MemorySpreadSpectrumSupport);
        phm_cap_set(hwmgr->platform_descriptor.platformCaps,
-                   PHM_PlatformCaps_EVV);
+                       PHM_PlatformCaps_EngineSpreadSpectrumSupport);
        return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
index 953e0c9..9001ef6 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
@@ -315,8 +315,8 @@ int atomctrl_get_engine_pll_dividers_kong(struct pp_hwmgr 
*hwmgr,
                                          uint32_t clock_value,
                                          pp_atomctrl_clock_dividers_kong 
*dividers)
 {
-       COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 pll_parameters;
        int result;
+       COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 pll_parameters;
 
        pll_parameters.ulClock = cpu_to_le32(clock_value);
 
@@ -470,7 +470,7 @@ uint32_t atomctrl_get_reference_clock(struct pp_hwmgr 
*hwmgr)
  * SET_VOLTAGE_TYPE_ASIC_MVDDC, SET_VOLTAGE_TYPE_ASIC_MVDDQ.
  * voltage_mode is one of ATOM_SET_VOLTAGE, ATOM_SET_VOLTAGE_PHASE
  */
-bool atomctrl_is_voltage_controled_by_gpio_v3(
+bool atomctrl_is_voltage_controlled_by_gpio_v3(
                struct pp_hwmgr *hwmgr,
                uint8_t voltage_type,
                uint8_t voltage_mode)
@@ -1418,3 +1418,83 @@ int  atomctrl_get_svi2_info(struct pp_hwmgr *hwmgr, 
uint8_t voltage_type,
 
        return 0;
 }
+
+int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t 
*virtual_voltage_id)
+{
+       int result;
+       SET_VOLTAGE_PS_ALLOCATION allocation;
+       SET_VOLTAGE_PARAMETERS_V1_3 *voltage_parameters =
+                       (SET_VOLTAGE_PARAMETERS_V1_3 
*)&allocation.sASICSetVoltage;
+
+       voltage_parameters->ucVoltageMode = ATOM_GET_LEAKAGE_ID;
+
+       result = cgs_atom_exec_cmd_table(hwmgr->device,
+                       GetIndexIntoMasterTable(COMMAND, SetVoltage),
+                       voltage_parameters);
+
+       *virtual_voltage_id = voltage_parameters->usVoltageLevel;
+
+       return result;
+}
+
+int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,
+                                       uint16_t *vddc, uint16_t *vddci,
+                                       uint16_t virtual_voltage_id,
+                                       uint16_t efuse_voltage_id)
+{
+       int i, j;
+       int ix;
+       u16 *leakage_bin, *vddc_id_buf, *vddc_buf, *vddci_id_buf, *vddci_buf;
+       ATOM_ASIC_PROFILING_INFO_V2_1 *profile;
+
+       *vddc = 0;
+       *vddci = 0;
+
+       ix = GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo);
+
+       profile = (ATOM_ASIC_PROFILING_INFO_V2_1 *)
+                       cgs_atom_get_data_table(hwmgr->device,
+                                       ix,
+                                       NULL, NULL, NULL);
+       if (!profile)
+               return -EINVAL;
+
+       if ((profile->asHeader.ucTableFormatRevision >= 2) &&
+               (profile->asHeader.ucTableContentRevision >= 1) &&
+               (profile->asHeader.usStructureSize >= 
sizeof(ATOM_ASIC_PROFILING_INFO_V2_1))) {
+               leakage_bin = (u16 *)((char *)profile + 
profile->usLeakageBinArrayOffset);
+               vddc_id_buf = (u16 *)((char *)profile + 
profile->usElbVDDC_IdArrayOffset);
+               vddc_buf = (u16 *)((char *)profile + 
profile->usElbVDDC_LevelArrayOffset);
+               if (profile->ucElbVDDC_Num > 0) {
+                       for (i = 0; i < profile->ucElbVDDC_Num; i++) {
+                               if (vddc_id_buf[i] == virtual_voltage_id) {
+                                       for (j = 0; j < 
profile->ucLeakageBinNum; j++) {
+                                               if (efuse_voltage_id <= 
leakage_bin[j]) {
+                                                       *vddc = vddc_buf[j * 
profile->ucElbVDDC_Num + i];
+                                                       break;
+                                               }
+                                       }
+                                       break;
+                               }
+                       }
+               }
+
+               vddci_id_buf = (u16 *)((char *)profile + 
profile->usElbVDDCI_IdArrayOffset);
+               vddci_buf   = (u16 *)((char *)profile + 
profile->usElbVDDCI_LevelArrayOffset);
+               if (profile->ucElbVDDCI_Num > 0) {
+                       for (i = 0; i < profile->ucElbVDDCI_Num; i++) {
+                               if (vddci_id_buf[i] == virtual_voltage_id) {
+                                       for (j = 0; j < 
profile->ucLeakageBinNum; j++) {
+                                               if (efuse_voltage_id <= 
leakage_bin[j]) {
+                                                       *vddci = vddci_buf[j * 
profile->ucElbVDDC_Num + i];
+                                                       break;
+                                               }
+                                       }
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h 
b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
index e9fe2e8..c44a920 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
@@ -291,7 +291,7 @@ struct pp_atom_ctrl__avfs_parameters {
 extern int atomctrl_get_memory_pll_dividers_si(struct pp_hwmgr *hwmgr, 
uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param, bool 
strobe_mode);
 extern int atomctrl_get_engine_pll_dividers_vi(struct pp_hwmgr *hwmgr, 
uint32_t clock_value, pp_atomctrl_clock_dividers_vi *dividers);
 extern int atomctrl_get_dfs_pll_dividers_vi(struct pp_hwmgr *hwmgr, uint32_t 
clock_value, pp_atomctrl_clock_dividers_vi *dividers);
-extern bool atomctrl_is_voltage_controled_by_gpio_v3(struct pp_hwmgr *hwmgr, 
uint8_t voltage_type, uint8_t voltage_mode);
+extern bool atomctrl_is_voltage_controlled_by_gpio_v3(struct pp_hwmgr *hwmgr, 
uint8_t voltage_type, uint8_t voltage_mode);
 extern int atomctrl_get_voltage_table_v3(struct pp_hwmgr *hwmgr, uint8_t 
voltage_type, uint8_t voltage_mode, pp_atomctrl_voltage_table *voltage_table);
 extern int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr,
                uint32_t clock_value, pp_atomctrl_memory_clock_param 
*mpll_param);
@@ -314,5 +314,11 @@ extern int atomctrl_get_voltage_evv_on_sclk_ai(struct 
pp_hwmgr *hwmgr, uint8_t v
 extern int  atomctrl_get_svi2_info(struct pp_hwmgr *hwmgr, uint8_t 
voltage_type,
                                uint8_t *svd_gpio_id, uint8_t *svc_gpio_id,
                                uint16_t *load_line);
+
+extern int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,
+                                       uint16_t *vddc, uint16_t *vddci,
+                                       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);
 #endif
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index b1ad424..45045a6 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -26,6 +26,7 @@
 #include <linux/fb.h>
 #include <asm/div64.h>
 #include "linux/delay.h"
+#include <drm/amdgpu_drm.h>
 #include "pp_acpi.h"
 #include "ppatomctrl.h"
 #include "atombios.h"
@@ -555,7 +556,6 @@ static int smu7_setup_default_pcie_table(struct pp_hwmgr 
*hwmgr)
        phm_reset_single_dpm_table(&data->dpm_table.pcie_speed_table,
                                        tmp,
                                        MAX_REGULAR_DPM_NUMBER);
-
        if (pcie_table != NULL) {
                /* max_entry is used to make sure we reserve one PCIE level
                 * for boot level (fix for A+A PSPP issue).
@@ -689,7 +689,7 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr)
                                allowed_vdd_sclk_table->entries[i].clk) {
                        
data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].value =
                                allowed_vdd_sclk_table->entries[i].clk;
-                       
data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].enabled 
= 1; /*(i==0) ? 1 : 0; to do */
+                       
data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].enabled 
= (i == 0) ? 1 : 0;
                        data->dpm_table.sclk_table.count++;
                }
        }
@@ -703,7 +703,7 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr)
                        allowed_vdd_mclk_table->entries[i].clk) {
                        
data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].value =
                                allowed_vdd_mclk_table->entries[i].clk;
-                       
data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].enabled 
= 1; /*(i==0) ? 1 : 0; */
+                       
data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].enabled 
= (i == 0) ? 1 : 0;
                        data->dpm_table.mclk_table.count++;
                }
        }
@@ -963,13 +963,24 @@ static int smu7_enable_sclk_mclk_dpm(struct pp_hwmgr 
*hwmgr)
 
                PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1);
 
-               cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_MC0_CNTL, 0x5);
-               cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_MC1_CNTL, 0x5);
-               cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_CPL_CNTL, 0x100005);
-               udelay(10);
-               cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_MC0_CNTL, 0x400005);
-               cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_MC1_CNTL, 0x400005);
-               cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_CPL_CNTL, 0x500005);
+
+               if (hwmgr->chip_family == AMDGPU_FAMILY_CI) {
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
0xc0400d30, 0x5);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
0xc0400d3c, 0x5);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
0xc0400d80, 0x100005);
+                       udelay(10);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
0xc0400d30, 0x400005);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
0xc0400d3c, 0x400005);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
0xc0400d80, 0x500005);
+               } else {
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_MC0_CNTL, 0x5);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_MC1_CNTL, 0x5);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_CPL_CNTL, 0x100005);
+                       udelay(10);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_MC0_CNTL, 0x400005);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_MC1_CNTL, 0x400005);
+                       cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 
ixLCAC_CPL_CNTL, 0x500005);
+               }
        }
 
        return 0;
@@ -998,6 +1009,10 @@ static int smu7_start_dpm(struct pp_hwmgr *hwmgr)
        PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__PCIE,
                        SWRST_COMMAND_1, RESETLC, 0x0);
 
+       if (hwmgr->chip_family == AMDGPU_FAMILY_CI)
+               cgs_write_register(hwmgr->device, 0x1488,
+                       (cgs_read_register(hwmgr->device, 0x1488) & ~0x1));
+
        if (smu7_enable_sclk_mclk_dpm(hwmgr)) {
                pr_err("Failed to enable Sclk DPM and Mclk DPM!");
                return -EINVAL;
@@ -1389,16 +1404,33 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr 
*hwmgr)
                                                &tmp3);
                tmp3 = (tmp3 >> 5) & 0x3;
                data->vddc_phase_shed_control = ((tmp3 << 1) | (tmp3 >> 1)) & 
0x3;
+       } else if (hwmgr->chip_family == AMDGPU_FAMILY_CI) {
+               data->vddc_phase_shed_control = 1;
+       } else {
+               data->vddc_phase_shed_control = 0;
+       }
+
+       if (hwmgr->chip_id  == CHIP_HAWAII) {
+               data->thermal_temp_setting.temperature_low = 94500;
+               data->thermal_temp_setting.temperature_high = 95000;
+               data->thermal_temp_setting.temperature_shutdown = 104000;
+       } else {
+               data->thermal_temp_setting.temperature_low = 99500;
+               data->thermal_temp_setting.temperature_high = 100000;
+               data->thermal_temp_setting.temperature_shutdown = 104000;
        }
 
        data->fast_watermark_threshold = 100;
-       if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+       if (atomctrl_is_voltage_controlled_by_gpio_v3(hwmgr,
                        VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2))
                data->voltage_control = SMU7_VOLTAGE_CONTROL_BY_SVID2;
+       else if (atomctrl_is_voltage_controlled_by_gpio_v3(hwmgr,
+                       VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_GPIO_LUT))
+               data->voltage_control = SMU7_VOLTAGE_CONTROL_BY_GPIO;
 
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_ControlVDDGFX)) {
-               if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+               if (atomctrl_is_voltage_controlled_by_gpio_v3(hwmgr,
                        VOLTAGE_TYPE_VDDGFX, VOLTAGE_OBJ_SVID2)) {
                        data->vdd_gfx_control = SMU7_VOLTAGE_CONTROL_BY_SVID2;
                }
@@ -1406,25 +1438,24 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr 
*hwmgr)
 
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_EnableMVDDControl)) {
-               if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+               if (atomctrl_is_voltage_controlled_by_gpio_v3(hwmgr,
                                VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_GPIO_LUT))
                        data->mvdd_control = SMU7_VOLTAGE_CONTROL_BY_GPIO;
-               else if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+               else if (atomctrl_is_voltage_controlled_by_gpio_v3(hwmgr,
                                VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_SVID2))
                        data->mvdd_control = SMU7_VOLTAGE_CONTROL_BY_SVID2;
        }
 
-       if (SMU7_VOLTAGE_CONTROL_NONE == data->vdd_gfx_control) {
+       if (SMU7_VOLTAGE_CONTROL_NONE == data->vdd_gfx_control)
                phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_ControlVDDGFX);
-       }
 
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_ControlVDDCI)) {
-               if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+               if (atomctrl_is_voltage_controlled_by_gpio_v3(hwmgr,
                                VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_GPIO_LUT))
                        data->vddci_control = SMU7_VOLTAGE_CONTROL_BY_GPIO;
-               else if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+               else if (atomctrl_is_voltage_controlled_by_gpio_v3(hwmgr,
                                VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_SVID2))
                        data->vddci_control = SMU7_VOLTAGE_CONTROL_BY_SVID2;
        }
@@ -2060,6 +2091,7 @@ static int smu7_patch_vddc(struct pp_hwmgr *hwmgr,
                        smu7_patch_ppt_v0_with_vdd_leakage(hwmgr, 
&tab->entries[i].v,
                                                &data->vddc_leakage);
 
+
        return 0;
 }
 
@@ -2274,9 +2306,8 @@ static int 
smu7_set_private_data_based_on_pptable_v0(struct pp_hwmgr *hwmgr)
                data->max_vddci_in_pptable = 
(uint16_t)allowed_mclk_vddci_table->entries[allowed_mclk_vddci_table->count - 
1].v;
        }
 
-       if (hwmgr->dyn_state.vddci_dependency_on_mclk != NULL && 
hwmgr->dyn_state.vddci_dependency_on_mclk->count > 1)
+       if (hwmgr->dyn_state.vddci_dependency_on_mclk != NULL && 
hwmgr->dyn_state.vddci_dependency_on_mclk->count >= 1)
                hwmgr->dyn_state.max_clock_voltage_on_ac.vddci = 
hwmgr->dyn_state.vddci_dependency_on_mclk->entries[hwmgr->dyn_state.vddci_dependency_on_mclk->count
 - 1].v;
-
        return 0;
 }
 
@@ -2290,10 +2321,38 @@ static int smu7_hwmgr_backend_fini(struct pp_hwmgr 
*hwmgr)
        return 0;
 }
 
+static int smu7_get_elb_voltages(struct pp_hwmgr *hwmgr)
+{
+       uint16_t virtual_voltage_id, vddc, vddci, efuse_voltage_id;
+       struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+       int i;
+
+       if (atomctrl_get_leakage_id_from_efuse(hwmgr, &efuse_voltage_id) == 0) {
+               for (i = 0; i < SMU7_MAX_LEAKAGE_COUNT; i++) {
+                       virtual_voltage_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;
+                       if (atomctrl_get_leakage_vddc_base_on_leakage(hwmgr, 
&vddc, &vddci,
+                                                               
virtual_voltage_id,
+                                                               
efuse_voltage_id) == 0) {
+                               if (vddc != 0 && vddc != virtual_voltage_id) {
+                                       
data->vddc_leakage.actual_voltage[data->vddc_leakage.count] = vddc;
+                                       
data->vddc_leakage.leakage_id[data->vddc_leakage.count] = virtual_voltage_id;
+                                       data->vddc_leakage.count++;
+                               }
+                               if (vddci != 0 && vddci != virtual_voltage_id) {
+                                       
data->vddci_leakage.actual_voltage[data->vddci_leakage.count] = vddci;
+                                       
data->vddci_leakage.leakage_id[data->vddci_leakage.count] = virtual_voltage_id;
+                                       data->vddci_leakage.count++;
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
 static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
 {
        struct smu7_hwmgr *data;
-       int result;
+       int result = 0;
 
        data = kzalloc(sizeof(struct smu7_hwmgr), GFP_KERNEL);
        if (data == NULL)
@@ -2304,11 +2363,15 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr 
*hwmgr)
        smu7_init_dpm_defaults(hwmgr);
 
        /* Get leakage voltage based on leakage ID. */
-       result = smu7_get_evv_voltages(hwmgr);
-
-       if (result) {
-               pr_info("Get EVV Voltage Failed.  Abort Driver loading!\n");
-               return -EINVAL;
+       if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+                       PHM_PlatformCaps_EVV)) {
+               result = smu7_get_evv_voltages(hwmgr);
+               if (result) {
+                       pr_info("Get EVV Voltage Failed.  Abort Driver 
loading!\n");
+                       return -EINVAL;
+               }
+       } else {
+               smu7_get_elb_voltages(hwmgr);
        }
 
        if (hwmgr->pp_table_version == PP_TABLE_V1) {
@@ -2425,7 +2488,6 @@ static int smu7_upload_dpm_level_enable_mask(struct 
pp_hwmgr *hwmgr)
                                        PPSMC_MSG_SCLKDPM_SetEnabledMask,
                                        
data->dpm_level_enable_mask.sclk_dpm_enable_mask);
        }
-
        if (!data->mclk_dpm_key_disabled) {
                if (data->dpm_level_enable_mask.mclk_dpm_enable_mask)
                        smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
@@ -3776,11 +3838,14 @@ static int 
smu7_notify_link_speed_change_after_state_change(
 static int smu7_notify_smc_display(struct pp_hwmgr *hwmgr)
 {
        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+       int ret = 0;
 
-       if (hwmgr->feature_mask & PP_VBI_TIME_SUPPORT_MASK)
+       if (hwmgr->feature_mask & PP_VBI_TIME_SUPPORT_MASK) {
                smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
                        (PPSMC_Msg)PPSMC_MSG_SetVBITimeout, 
data->frame_time_x2);
-       return (smum_send_msg_to_smc(hwmgr->smumgr, 
(PPSMC_Msg)PPSMC_HasDisplay) == 0) ?  0 : -EINVAL;
+               ret = (smum_send_msg_to_smc(hwmgr->smumgr, 
(PPSMC_Msg)PPSMC_HasDisplay) == 0) ?  0 : -EINVAL;
+       }
+       return ret;
 }
 
 static int smu7_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void 
*input)
@@ -4116,7 +4181,6 @@ static int smu7_get_memory_type(struct pp_hwmgr *hwmgr)
        data->is_memory_gddr5 = (MC_SEQ_MISC0_GDDR5_VALUE ==
                        ((temp & MC_SEQ_MISC0_GDDR5_MASK) >>
                         MC_SEQ_MISC0_GDDR5_SHIFT));
-
        return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
index 0f75af3..ece5709 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
@@ -905,7 +905,6 @@ int smu7_enable_power_containment(struct pp_hwmgr *hwmgr)
                        if (0 == smc_result) {
                                uint32_t default_limit =
                                        
(uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256);
-
                                data->power_containment_features |=
                                                
POWERCONTAINMENT_FEATURE_PkgPwrLimit;
 
@@ -979,7 +978,10 @@ int smu7_power_control_set_level(struct pp_hwmgr *hwmgr)
                /* SMC requested that target_tdp to be 7 bit fraction in DPM 
table
                 * but message to be 8 bit fraction for messages
                 */
-               target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 
256)) / 100;
+                if (hwmgr->chip_id > CHIP_TONGA)
+                       target_tdp = ((100 + adjust_percent) * 
(int)(cac_table->usTDP * 256)) / 100;
+               else
+                       target_tdp = ((100 + adjust_percent) * 
(int)(cac_table->usConfigurableTDP)) / 100;
                result = smu7_set_overdriver_target_tdp(hwmgr, 
(uint32_t)target_tdp);
        }
 
-- 
1.9.1

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

Reply via email to