[PATCH 2/4] drm/amd/powerplay: add ci support in hwmgr
Rex Zhu
Rex.Zhu at amd.com
Wed Sep 13 13:08:34 UTC 2017
Change-Id: Ifd9693470534d96bfa99a6de2fa79c84d6b97662
Signed-off-by: Rex Zhu <Rex.Zhu at 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
More information about the amd-gfx
mailing list