drm/amd/powerplay: update baffin & ellesmere smc_sk firmware.
sync the code form catalyst CL:#1230866. Signed-off-by: yanyang1 <Young.Yang@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
a6ece7ffd9
commit
e85c7d664d
|
@ -222,6 +222,22 @@ void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr)
|
|||
" found a available voltage in VDDC DPM Table \n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable voltage control
|
||||
*
|
||||
* @param pHwMgr the address of the powerplay hardware manager.
|
||||
* @return always PP_Result_OK
|
||||
*/
|
||||
int ellesmere_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
PP_ASSERT_WITH_CODE(
|
||||
(hwmgr->smumgr->smumgr_funcs->send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Voltage_Cntl_Enable) == 0),
|
||||
"Failed to enable voltage DPM during DPM Start Function!",
|
||||
return 1;
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we want to support voltage control
|
||||
|
@ -586,6 +602,10 @@ static int ellesmere_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
|
|||
pcie_table->entries[i].lane_width));
|
||||
}
|
||||
data->dpm_table.pcie_speed_table.count = max_entry - 1;
|
||||
|
||||
/* Setup BIF_SCLK levels */
|
||||
for (i = 0; i < max_entry; i++)
|
||||
data->bif_sclk_table[i] = pcie_table->entries[i].pcie_sclk;
|
||||
} else {
|
||||
/* Hardcode Pcie Table */
|
||||
phm_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 0,
|
||||
|
@ -938,9 +958,13 @@ static int ellesmere_calculate_sclk_params(struct pp_hwmgr *hwmgr,
|
|||
sclk_setting->Fcw_frac = dividers.usSclk_fcw_frac;
|
||||
sclk_setting->Pcc_fcw_int = dividers.usPcc_fcw_int;
|
||||
sclk_setting->PllRange = dividers.ucSclkPllRange;
|
||||
sclk_setting->Sclk_slew_rate = 0x400;
|
||||
sclk_setting->Pcc_up_slew_rate = dividers.usPcc_fcw_slew_frac;
|
||||
sclk_setting->Pcc_down_slew_rate = 0xffff;
|
||||
sclk_setting->SSc_En = dividers.ucSscEnable;
|
||||
sclk_setting->Fcw1_int = dividers.usSsc_fcw1_int;
|
||||
sclk_setting->Fcw1_frac = dividers.usSsc_fcw1_frac;
|
||||
sclk_setting->Sclk_ss_slew_rate = dividers.usSsc_fcw_slew_frac;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1174,8 +1198,12 @@ static int ellesmere_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
|
|||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_int);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_frac);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_fcw_int);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_slew_rate);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_up_slew_rate);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_down_slew_rate);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_int);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_frac);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_ss_slew_rate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1458,8 +1486,12 @@ static int ellesmere_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
|
|||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_int);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_frac);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_fcw_int);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_slew_rate);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_up_slew_rate);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_down_slew_rate);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_int);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_frac);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate);
|
||||
|
||||
if (!data->mclk_dpm_key_disabled) {
|
||||
/* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */
|
||||
|
@ -1966,6 +1998,7 @@ static int ellesmere_init_smc_table(struct pp_hwmgr *hwmgr)
|
|||
const struct ellesmere_ulv_parm *ulv = &(data->ulv);
|
||||
uint8_t i;
|
||||
struct pp_atomctrl_gpio_pin_assignment gpio_pin;
|
||||
pp_atomctrl_clock_dividers_vi dividers;
|
||||
|
||||
result = ellesmere_setup_default_dpm_tables(hwmgr);
|
||||
PP_ASSERT_WITH_CODE(0 == result,
|
||||
|
@ -2121,6 +2154,17 @@ static int ellesmere_init_smc_table(struct pp_hwmgr *hwmgr)
|
|||
table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE;
|
||||
}
|
||||
|
||||
/* Populate BIF_SCLK levels into SMC DPM table */
|
||||
for (i = 0; i <= data->dpm_table.pcie_speed_table.count; i++) {
|
||||
result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, data->bif_sclk_table[i], ÷rs);
|
||||
PP_ASSERT_WITH_CODE((result == 0), "Can not find DFS divide id for Sclk", return result);
|
||||
|
||||
if (i == 0)
|
||||
table->Ulv.BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider));
|
||||
else
|
||||
table->LinkLevel[i-1].BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider));
|
||||
}
|
||||
|
||||
for (i = 0; i < SMU74_MAX_ENTRIES_SMIO; i++)
|
||||
table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]);
|
||||
|
||||
|
@ -2284,12 +2328,13 @@ static int ellesmere_start_dpm(struct pp_hwmgr *hwmgr)
|
|||
VoltageChangeTimeout), 0x1000);
|
||||
PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__PCIE,
|
||||
SWRST_COMMAND_1, RESETLC, 0x0);
|
||||
|
||||
/*
|
||||
PP_ASSERT_WITH_CODE(
|
||||
(0 == smum_send_msg_to_smc(hwmgr->smumgr,
|
||||
PPSMC_MSG_Voltage_Cntl_Enable)),
|
||||
"Failed to enable voltage DPM during DPM Start Function!",
|
||||
return -1);
|
||||
*/
|
||||
|
||||
if (ellesmere_enable_sclk_mclk_dpm(hwmgr)) {
|
||||
printk(KERN_ERR "Failed to enable Sclk DPM and Mclk DPM!");
|
||||
|
@ -2450,6 +2495,10 @@ int ellesmere_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
|
|||
PP_ASSERT_WITH_CODE((0 == tmp_result),
|
||||
"Failed to enable SCLK control!", result = tmp_result);
|
||||
|
||||
tmp_result = ellesmere_enable_smc_voltage_controller(hwmgr);
|
||||
PP_ASSERT_WITH_CODE((0 == tmp_result),
|
||||
"Failed to enable voltage control!", result = tmp_result);
|
||||
|
||||
tmp_result = ellesmere_enable_ulv(hwmgr);
|
||||
PP_ASSERT_WITH_CODE((0 == tmp_result),
|
||||
"Failed to enable ULV!", result = tmp_result);
|
||||
|
|
|
@ -274,6 +274,7 @@ struct ellesmere_hwmgr {
|
|||
|
||||
/* ---- DI/DT ---- */
|
||||
struct ellesmere_display_timing display_timing;
|
||||
uint32_t bif_sclk_table[SMU74_MAX_LEVELS_LINK];
|
||||
|
||||
/* ---- Thermal Temperature Setting ---- */
|
||||
struct ellesmere_dpmlevel_enable_mask dpm_level_enable_mask;
|
||||
|
|
|
@ -92,6 +92,8 @@ typedef struct phm_ppt_v1_voltage_lookup_table phm_ppt_v1_voltage_lookup_table;
|
|||
struct phm_ppt_v1_pcie_record {
|
||||
uint8_t gen_speed;
|
||||
uint8_t lane_width;
|
||||
uint16_t usreserved;
|
||||
uint32_t pcie_sclk;
|
||||
};
|
||||
typedef struct phm_ppt_v1_pcie_record phm_ppt_v1_pcie_record;
|
||||
|
||||
|
|
|
@ -209,6 +209,20 @@ typedef struct _ATOM_Tonga_PCIE_Table {
|
|||
ATOM_Tonga_PCIE_Record entries[1]; /* Dynamically allocate entries. */
|
||||
} ATOM_Tonga_PCIE_Table;
|
||||
|
||||
typedef struct _ATOM_Ellesmere_PCIE_Record {
|
||||
UCHAR ucPCIEGenSpeed;
|
||||
UCHAR usPCIELaneWidth;
|
||||
UCHAR ucReserved[2];
|
||||
ULONG ulPCIE_Sclk;
|
||||
} ATOM_Ellesmere_PCIE_Record;
|
||||
|
||||
typedef struct _ATOM_Ellesmere_PCIE_Table {
|
||||
UCHAR ucRevId;
|
||||
UCHAR ucNumEntries; /* Number of entries. */
|
||||
ATOM_Ellesmere_PCIE_Record entries[1]; /* Dynamically allocate entries. */
|
||||
} ATOM_Ellesmere_PCIE_Table;
|
||||
|
||||
|
||||
typedef struct _ATOM_Tonga_MM_Dependency_Record {
|
||||
UCHAR ucVddcInd; /* VDDC voltage */
|
||||
USHORT usVddgfxOffset; /* Offset relative to VDDC voltage */
|
||||
|
|
|
@ -448,14 +448,17 @@ static int get_sclk_voltage_dependency_table(
|
|||
static int get_pcie_table(
|
||||
struct pp_hwmgr *hwmgr,
|
||||
phm_ppt_v1_pcie_table **pp_tonga_pcie_table,
|
||||
const ATOM_Tonga_PCIE_Table * atom_pcie_table
|
||||
const PPTable_Generic_SubTable_Header * pTable
|
||||
)
|
||||
{
|
||||
uint32_t table_size, i, pcie_count;
|
||||
phm_ppt_v1_pcie_table *pcie_table;
|
||||
struct phm_ppt_v1_information *pp_table_information =
|
||||
(struct phm_ppt_v1_information *)(hwmgr->pptable);
|
||||
PP_ASSERT_WITH_CODE((0 != atom_pcie_table->ucNumEntries),
|
||||
|
||||
if (pTable->ucRevId < 1) {
|
||||
const ATOM_Tonga_PCIE_Table *atom_pcie_table = (ATOM_Tonga_PCIE_Table *)pTable;
|
||||
PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0),
|
||||
"Invalid PowerPlay Table!", return -1);
|
||||
|
||||
table_size = sizeof(uint32_t) +
|
||||
|
@ -463,7 +466,7 @@ static int get_pcie_table(
|
|||
|
||||
pcie_table = (phm_ppt_v1_pcie_table *)kzalloc(table_size, GFP_KERNEL);
|
||||
|
||||
if (NULL == pcie_table)
|
||||
if (pcie_table == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(pcie_table, 0x00, table_size);
|
||||
|
@ -489,6 +492,46 @@ static int get_pcie_table(
|
|||
}
|
||||
|
||||
*pp_tonga_pcie_table = pcie_table;
|
||||
} else {
|
||||
/* Ellesmere/Baffin and newer. */
|
||||
const ATOM_Ellesmere_PCIE_Table *atom_pcie_table = (ATOM_Ellesmere_PCIE_Table *)pTable;
|
||||
PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0),
|
||||
"Invalid PowerPlay Table!", return -1);
|
||||
|
||||
table_size = sizeof(uint32_t) +
|
||||
sizeof(phm_ppt_v1_pcie_record) * atom_pcie_table->ucNumEntries;
|
||||
|
||||
pcie_table = (phm_ppt_v1_pcie_table *)kzalloc(table_size, GFP_KERNEL);
|
||||
|
||||
if (pcie_table == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(pcie_table, 0x00, table_size);
|
||||
|
||||
/*
|
||||
* Make sure the number of pcie entries are less than or equal to sclk dpm levels.
|
||||
* Since first PCIE entry is for ULV, #pcie has to be <= SclkLevel + 1.
|
||||
*/
|
||||
pcie_count = (pp_table_information->vdd_dep_on_sclk->count) + 1;
|
||||
if ((uint32_t)atom_pcie_table->ucNumEntries <= pcie_count)
|
||||
pcie_count = (uint32_t)atom_pcie_table->ucNumEntries;
|
||||
else
|
||||
printk(KERN_ERR "[ powerplay ] Number of Pcie Entries exceed the number of SCLK Dpm Levels! \
|
||||
Disregarding the excess entries... \n");
|
||||
|
||||
pcie_table->count = pcie_count;
|
||||
|
||||
for (i = 0; i < pcie_count; i++) {
|
||||
pcie_table->entries[i].gen_speed =
|
||||
atom_pcie_table->entries[i].ucPCIEGenSpeed;
|
||||
pcie_table->entries[i].lane_width =
|
||||
atom_pcie_table->entries[i].usPCIELaneWidth;
|
||||
pcie_table->entries[i].pcie_sclk =
|
||||
atom_pcie_table->entries[i].ulPCIE_Sclk;
|
||||
}
|
||||
|
||||
*pp_tonga_pcie_table = pcie_table;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -668,8 +711,8 @@ static int init_clock_voltage_dependency(
|
|||
const ATOM_Tonga_Hard_Limit_Table *pHardLimits =
|
||||
(const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) +
|
||||
le16_to_cpu(powerplay_table->usHardLimitTableOffset));
|
||||
const ATOM_Tonga_PCIE_Table *pcie_table =
|
||||
(const ATOM_Tonga_PCIE_Table *)(((unsigned long) powerplay_table) +
|
||||
const PPTable_Generic_SubTable_Header *pcie_table =
|
||||
(const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
|
||||
le16_to_cpu(powerplay_table->usPCIETableOffset));
|
||||
|
||||
pp_table_information->vdd_dep_on_sclk = NULL;
|
||||
|
|
|
@ -345,7 +345,6 @@ static int ellesmere_upload_smc_firmware_data(struct pp_smumgr *smumgr, uint32_t
|
|||
cgs_write_register(smumgr->device, mmSMC_IND_INDEX_11, 0x20000);
|
||||
SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 1);
|
||||
|
||||
|
||||
for (; byte_count >= 4; byte_count -= 4)
|
||||
cgs_write_register(smumgr->device, mmSMC_IND_DATA_11, *src++);
|
||||
|
||||
|
@ -364,6 +363,9 @@ static enum cgs_ucode_id ellesmere_convert_fw_type_to_cgs(uint32_t fw_type)
|
|||
case UCODE_ID_SMU:
|
||||
result = CGS_UCODE_ID_SMU;
|
||||
break;
|
||||
case UCODE_ID_SMU_SK:
|
||||
result = CGS_UCODE_ID_SMU_SK;
|
||||
break;
|
||||
case UCODE_ID_SDMA0:
|
||||
result = CGS_UCODE_ID_SDMA0;
|
||||
break;
|
||||
|
@ -401,14 +403,18 @@ static enum cgs_ucode_id ellesmere_convert_fw_type_to_cgs(uint32_t fw_type)
|
|||
static int ellesmere_upload_smu_firmware_image(struct pp_smumgr *smumgr)
|
||||
{
|
||||
int result = 0;
|
||||
struct ellesmere_smumgr *smu_data = (struct ellesmere_smumgr *)(smumgr->backend);
|
||||
|
||||
struct cgs_firmware_info info = {0};
|
||||
|
||||
if (smu_data->security_hard_key == 1)
|
||||
cgs_get_firmware_info(smumgr->device,
|
||||
ellesmere_convert_fw_type_to_cgs(UCODE_ID_SMU), &info);
|
||||
else
|
||||
cgs_get_firmware_info(smumgr->device,
|
||||
ellesmere_convert_fw_type_to_cgs(UCODE_ID_SMU_SK), &info);
|
||||
|
||||
/* TO DO cgs_init_samu_load_smu(smumgr->device, (uint32_t *)info.kptr, info.image_size, smu_data->post_initial_boot);*/
|
||||
|
||||
result = ellesmere_upload_smc_firmware_data(smumgr, info.image_size, (uint32_t *)info.kptr, ELLESMERE_SMC_SIZE);
|
||||
|
||||
return result;
|
||||
|
@ -798,13 +804,11 @@ static int ellesmere_start_smu_in_protection_mode(struct pp_smumgr *smumgr)
|
|||
SMU_STATUS, SMU_PASS))
|
||||
PP_ASSERT_WITH_CODE(false, "SMU Firmware start failed!", return -1);
|
||||
|
||||
|
||||
cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC, ixFIRMWARE_FLAGS, 0);
|
||||
|
||||
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
||||
SMC_SYSCON_RESET_CNTL, rst_reg, 1);
|
||||
|
||||
|
||||
SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
|
||||
SMC_SYSCON_RESET_CNTL, rst_reg, 0);
|
||||
|
||||
|
@ -860,12 +864,22 @@ static int ellesmere_start_smu(struct pp_smumgr *smumgr)
|
|||
/* Only start SMC if SMC RAM is not running */
|
||||
if (!ellesmere_is_smc_ram_running(smumgr)) {
|
||||
SMU_VFT_INTACT = false;
|
||||
smu_data->protected_mode = (uint8_t) (SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_MODE));
|
||||
smu_data->security_hard_key = (uint8_t) (SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_SEL));
|
||||
|
||||
/* Check if SMU is running in protected mode */
|
||||
if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_MODE))
|
||||
if (smu_data->protected_mode == 0) {
|
||||
result = ellesmere_start_smu_in_non_protection_mode(smumgr);
|
||||
else
|
||||
} else {
|
||||
result = ellesmere_start_smu_in_protection_mode(smumgr);
|
||||
|
||||
/* If failed, try with different security Key. */
|
||||
if (result != 0) {
|
||||
smu_data->security_hard_key ^= 1;
|
||||
result = ellesmere_start_smu_in_protection_mode(smumgr);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
PP_ASSERT_WITH_CODE(0, "Failed to load SMU ucode.", return result);
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ struct ellesmere_smumgr {
|
|||
uint32_t read_drm_straps_mc_address_low;
|
||||
uint32_t acpi_optimization;
|
||||
bool post_initial_boot;
|
||||
uint8_t protected_mode;
|
||||
uint8_t security_hard_key;
|
||||
struct ellesmere_avfs avfs;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue