From: Rex Zhu Date: Tue, 23 Aug 2016 03:57:30 +0000 (+0800) Subject: drm/amd/powerplay: use smu7 common functions and data on icelannd. X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=9c6d4956964d4b0282078dc348ca788dc3189d53;p=linux-beck.git drm/amd/powerplay: use smu7 common functions and data on icelannd. Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c index 5abe43360ec0..50aa23f15540 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c @@ -767,12 +767,7 @@ int iceland_program_voting_clients(struct pp_hwmgr *hwmgr) static int iceland_upload_firmware(struct pp_hwmgr *hwmgr) { - int ret = 0; - - if (!iceland_is_smc_ram_running(hwmgr->smumgr)) - ret = iceland_smu_upload_firmware_image(hwmgr->smumgr); - - return ret; + return 0; } /** @@ -789,7 +784,7 @@ static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) int result; bool error = 0; - result = iceland_read_smc_sram_dword(hwmgr->smumgr, + result = smu7_read_smc_sram_dword(hwmgr->smumgr, SMU71_FIRMWARE_HEADER_LOCATION + offsetof(SMU71_Firmware_Header, DpmTable), &tmp, data->sram_end); @@ -800,7 +795,7 @@ static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) error |= (0 != result); - result = iceland_read_smc_sram_dword(hwmgr->smumgr, + result = smu7_read_smc_sram_dword(hwmgr->smumgr, SMU71_FIRMWARE_HEADER_LOCATION + offsetof(SMU71_Firmware_Header, SoftRegisters), &tmp, data->sram_end); @@ -812,7 +807,7 @@ static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) error |= (0 != result); - result = iceland_read_smc_sram_dword(hwmgr->smumgr, + result = smu7_read_smc_sram_dword(hwmgr->smumgr, SMU71_FIRMWARE_HEADER_LOCATION + offsetof(SMU71_Firmware_Header, mcRegisterTable), &tmp, data->sram_end); @@ -821,7 +816,7 @@ static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) data->mc_reg_table_start = tmp; } - result = iceland_read_smc_sram_dword(hwmgr->smumgr, + result = smu7_read_smc_sram_dword(hwmgr->smumgr, SMU71_FIRMWARE_HEADER_LOCATION + offsetof(SMU71_Firmware_Header, FanTable), &tmp, data->sram_end); @@ -832,7 +827,7 @@ static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) error |= (0 != result); - result = iceland_read_smc_sram_dword(hwmgr->smumgr, + result = smu7_read_smc_sram_dword(hwmgr->smumgr, SMU71_FIRMWARE_HEADER_LOCATION + offsetof(SMU71_Firmware_Header, mcArbDramTimingTable), &tmp, data->sram_end); @@ -844,7 +839,7 @@ static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) error |= (0 != result); - result = iceland_read_smc_sram_dword(hwmgr->smumgr, + result = smu7_read_smc_sram_dword(hwmgr->smumgr, SMU71_FIRMWARE_HEADER_LOCATION + offsetof(SMU71_Firmware_Header, Version), &tmp, data->sram_end); @@ -855,7 +850,7 @@ static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) error |= (0 != result); - result = iceland_read_smc_sram_dword(hwmgr->smumgr, + result = smu7_read_smc_sram_dword(hwmgr->smumgr, SMU71_FIRMWARE_HEADER_LOCATION + offsetof(SMU71_Firmware_Header, UlvSettings), &tmp, data->sram_end); @@ -1507,7 +1502,7 @@ int iceland_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) } if (0 == result) { - result = iceland_copy_bytes_to_smc( + result = smu7_copy_bytes_to_smc( hwmgr->smumgr, data->arb_table_start, (uint8_t *)&arb_regs, @@ -2438,7 +2433,7 @@ static int iceland_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled; /* level count will send to smc once at init smc table and never change*/ - result = iceland_copy_bytes_to_smc(hwmgr->smumgr, level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, data->sram_end); + result = smu7_copy_bytes_to_smc(hwmgr->smumgr, level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, data->sram_end); if (0 != result) return result; @@ -2492,7 +2487,7 @@ static int iceland_populate_all_memory_levels(struct pp_hwmgr *hwmgr) data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; /* level count will send to smc once at init smc table and never change*/ - result = iceland_copy_bytes_to_smc(hwmgr->smumgr, + result = smu7_copy_bytes_to_smc(hwmgr->smumgr, level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, data->sram_end); if (0 != result) { @@ -2754,7 +2749,7 @@ static int iceland_init_smc_table(struct pp_hwmgr *hwmgr) table->BootMVdd = PP_HOST_TO_SMC_US(table->BootMVdd * VOLTAGE_SCALE); /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ - result = iceland_copy_bytes_to_smc(hwmgr->smumgr, data->dpm_table_start + + result = smu7_copy_bytes_to_smc(hwmgr->smumgr, data->dpm_table_start + offsetof(SMU71_Discrete_DpmTable, SystemFlags), (uint8_t *)&(table->SystemFlags), sizeof(SMU71_Discrete_DpmTable) - 3 * sizeof(SMU71_PIDController), @@ -2764,7 +2759,7 @@ static int iceland_init_smc_table(struct pp_hwmgr *hwmgr) "Failed to upload dpm data to SMC memory!", return result); /* Upload all ulv setting to SMC memory.(dpm level, dpm level count etc) */ - result = iceland_copy_bytes_to_smc(hwmgr->smumgr, + result = smu7_copy_bytes_to_smc(hwmgr->smumgr, data->ulv_settings_start, (uint8_t *)&(data->ulv_setting), sizeof(SMU71_Discrete_Ulv), @@ -2884,7 +2879,7 @@ int iceland_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr) PP_ASSERT_WITH_CODE(0 == result, "Failed to initialize MCRegTable for driver state!", return result;); - return iceland_copy_bytes_to_smc(hwmgr->smumgr, data->mc_reg_table_start, + return smu7_copy_bytes_to_smc(hwmgr->smumgr, data->mc_reg_table_start, (uint8_t *)&data->mc_reg_table, sizeof(SMU71_Discrete_MCRegisters), data->sram_end); } @@ -3047,15 +3042,6 @@ static int iceland_enable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) return iceland_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); } -static int iceland_tf_start_smc(struct pp_hwmgr *hwmgr) -{ - int ret = 0; - - if (!iceland_is_smc_ram_running(hwmgr->smumgr)) - ret = iceland_smu_start_smc(hwmgr->smumgr); - - return ret; -} /** * Programs the Deep Sleep registers @@ -3141,10 +3127,6 @@ static int iceland_enable_dpm_tasks(struct pp_hwmgr *hwmgr) PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to populate PM fuses!", return tmp_result); - /* start SMC */ - tmp_result = iceland_tf_start_smc(hwmgr); - PP_ASSERT_WITH_CODE((0 == tmp_result), - "Failed to start SMC!", return tmp_result); /* enable SCLK control */ tmp_result = iceland_enable_sclk_control(hwmgr); @@ -4636,7 +4618,7 @@ static int iceland_update_sclk_threshold(struct pp_hwmgr *hwmgr) CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); - result = iceland_copy_bytes_to_smc( + result = smu7_copy_bytes_to_smc( hwmgr->smumgr, data->dpm_table_start + offsetof(SMU71_Discrete_DpmTable, LowSclkInterruptThreshold), @@ -4670,7 +4652,7 @@ static int iceland_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr) address = data->mc_reg_table_start + (uint32_t)offsetof(SMU71_Discrete_MCRegisters, data[0]); - return iceland_copy_bytes_to_smc(hwmgr->smumgr, address, + return smu7_copy_bytes_to_smc(hwmgr->smumgr, address, (uint8_t *)&data->mc_reg_table.data[0], sizeof(SMU71_Discrete_MCRegisterSet) * data->dpm_table.mclk_table.count, data->sram_end); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.c index 041e9648e592..766280626836 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.c @@ -239,7 +239,7 @@ static int iceland_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offs const struct iceland_pt_defaults *defaults = data->power_tune_defaults; uint32_t temp; - if (iceland_read_smc_sram_dword(hwmgr->smumgr, + if (smu7_read_smc_sram_dword(hwmgr->smumgr, fuse_table_offset + offsetof(SMU71_Discrete_PmFuses, TdcWaterfallCtl), (uint32_t *)&temp, data->sram_end)) @@ -299,7 +299,7 @@ int iceland_populate_pm_fuses(struct pp_hwmgr *hwmgr) if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PowerContainment)) { - if (iceland_read_smc_sram_dword(hwmgr->smumgr, + if (smu7_read_smc_sram_dword(hwmgr->smumgr, SMU71_FIRMWARE_HEADER_LOCATION + offsetof(SMU71_Firmware_Header, PmFuseTable), &pm_fuse_table_offset, data->sram_end)) @@ -359,7 +359,7 @@ int iceland_populate_pm_fuses(struct pp_hwmgr *hwmgr) "Attempt to populate BapmVddCBaseLeakage Hi and Lo Sidd Failed!", return -EINVAL); - if (iceland_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, + if (smu7_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, (uint8_t *)&data->power_tune_table, sizeof(struct SMU71_Discrete_PmFuses), data->sram_end)) PP_ASSERT_WITH_CODE(false, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.c index 527f37022424..45d17d715640 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.c @@ -426,7 +426,7 @@ int tf_iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, void *input, void //fan_table.FanControl_GL_Flag = 1; - res = iceland_copy_bytes_to_smc(hwmgr->smumgr, data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), data->sram_end); + res = smu7_copy_bytes_to_smc(hwmgr->smumgr, data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), data->sram_end); /* TO DO FOR SOME DEVICE ID 0X692b, send this msg return invalid command. if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit != 0) res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanMinPwm, \ diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c index f50658332d9d..31b6de858317 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c @@ -36,119 +36,8 @@ #include "smu/smu_7_1_1_sh_mask.h" #include "cgs_common.h" -#define ICELAND_SMC_SIZE 0x20000 -#define BUFFER_SIZE 80000 -#define MAX_STRING_SIZE 15 -#define BUFFER_SIZETWO 131072 /*128 *1024*/ +#define ICELAND_SMC_SIZE 0x20000 -/** - * Set the address for reading/writing the SMC SRAM space. - * @param smumgr the address of the powerplay hardware manager. - * @param smcAddress the address in the SMC RAM to access. - */ -static int iceland_set_smc_sram_address(struct pp_smumgr *smumgr, - uint32_t smcAddress, uint32_t limit) -{ - if (smumgr == NULL || smumgr->device == NULL) - return -EINVAL; - PP_ASSERT_WITH_CODE((0 == (3 & smcAddress)), - "SMC address must be 4 byte aligned.", - return -1;); - - PP_ASSERT_WITH_CODE((limit > (smcAddress + 3)), - "SMC address is beyond the SMC RAM area.", - return -1;); - - cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, smcAddress); - SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); - - return 0; -} - -/** - * Copy bytes from an array into the SMC RAM space. - * - * @param smumgr the address of the powerplay SMU manager. - * @param smcStartAddress the start address in the SMC RAM to copy bytes to. - * @param src the byte array to copy the bytes from. - * @param byteCount the number of bytes to copy. - */ -int iceland_copy_bytes_to_smc(struct pp_smumgr *smumgr, - uint32_t smcStartAddress, const uint8_t *src, - uint32_t byteCount, uint32_t limit) -{ - uint32_t addr; - uint32_t data, orig_data; - int result = 0; - uint32_t extra_shift; - - if (smumgr == NULL || smumgr->device == NULL) - return -EINVAL; - PP_ASSERT_WITH_CODE((0 == (3 & smcStartAddress)), - "SMC address must be 4 byte aligned.", - return 0;); - - PP_ASSERT_WITH_CODE((limit > (smcStartAddress + byteCount)), - "SMC address is beyond the SMC RAM area.", - return 0;); - - addr = smcStartAddress; - - while (byteCount >= 4) { - /* - * Bytes are written into the - * SMC address space with the MSB first - */ - data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3]; - - result = iceland_set_smc_sram_address(smumgr, addr, limit); - - if (result) - goto out; - - cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data); - - src += 4; - byteCount -= 4; - addr += 4; - } - - if (0 != byteCount) { - /* Now write odd bytes left, do a read modify write cycle */ - data = 0; - - result = iceland_set_smc_sram_address(smumgr, addr, limit); - if (result) - goto out; - - orig_data = cgs_read_register(smumgr->device, - mmSMC_IND_DATA_0); - extra_shift = 8 * (4 - byteCount); - - while (byteCount > 0) { - data = (data << 8) + *src++; - byteCount--; - } - - data <<= extra_shift; - data |= (orig_data & ~((~0UL) << extra_shift)); - - result = iceland_set_smc_sram_address(smumgr, addr, limit); - if (result) - goto out; - - cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data); - } - -out: - return result; -} - -/** - * Deassert the reset'pin' (set it to high). - * - * @param smumgr the address of the powerplay hardware manager. - */ static int iceland_start_smc(struct pp_smumgr *smumgr) { SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, @@ -157,284 +46,15 @@ static int iceland_start_smc(struct pp_smumgr *smumgr) return 0; } -static void iceland_pp_reset_smc(struct pp_smumgr *smumgr) +static void iceland_reset_smc(struct pp_smumgr *smumgr) { SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 1); } -int iceland_program_jump_on_start(struct pp_smumgr *smumgr) -{ - static const unsigned char pData[] = { 0xE0, 0x00, 0x80, 0x40 }; - - iceland_copy_bytes_to_smc(smumgr, 0x0, pData, 4, sizeof(pData)+1); - return 0; -} - -/** - * Return if the SMC is currently running. - * - * @param smumgr the address of the powerplay hardware manager. - */ -bool iceland_is_smc_ram_running(struct pp_smumgr *smumgr) -{ - uint32_t val1, val2; - - val1 = SMUM_READ_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, - SMC_SYSCON_CLOCK_CNTL_0, ck_disable); - val2 = cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC, - ixSMC_PC_C); - - return ((0 == val1) && (0x20100 <= val2)); -} - -/** - * Send a message to the SMC, and wait for its response. - * - * @param smumgr the address of the powerplay hardware manager. - * @param msg the message to send. - * @return The response that came from the SMC. - */ -static int iceland_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg) -{ - if (smumgr == NULL || smumgr->device == NULL) - return -EINVAL; - - if (!iceland_is_smc_ram_running(smumgr)) - return -EINVAL; - - SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); - PP_ASSERT_WITH_CODE( - 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP), - "Failed to send Previous Message.", - ); - - cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg); - - SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); - PP_ASSERT_WITH_CODE( - 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP), - "Failed to send Message.", - ); - - return 0; -} - -/** - * Send a message to the SMC with parameter - * - * @param smumgr: the address of the powerplay hardware manager. - * @param msg: the message to send. - * @param parameter: the parameter to send - * @return The response that came from the SMC. - */ -static int iceland_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr, - uint16_t msg, uint32_t parameter) -{ - if (smumgr == NULL || smumgr->device == NULL) - return -EINVAL; - - cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter); - - return iceland_send_msg_to_smc(smumgr, msg); -} - -/* - * Read a 32bit value from the SMC SRAM space. - * ALL PARAMETERS ARE IN HOST BYTE ORDER. - * @param smumgr the address of the powerplay hardware manager. - * @param smcAddress the address in the SMC RAM to access. - * @param value and output parameter for the data read from the SMC SRAM. - */ -int iceland_read_smc_sram_dword(struct pp_smumgr *smumgr, - uint32_t smcAddress, uint32_t *value, - uint32_t limit) -{ - int result; - - result = iceland_set_smc_sram_address(smumgr, smcAddress, limit); - - if (0 != result) - return result; - - *value = cgs_read_register(smumgr->device, mmSMC_IND_DATA_0); - - return 0; -} - -/* - * Write a 32bit value to the SMC SRAM space. - * ALL PARAMETERS ARE IN HOST BYTE ORDER. - * @param smumgr the address of the powerplay hardware manager. - * @param smcAddress the address in the SMC RAM to access. - * @param value to write to the SMC SRAM. - */ -int iceland_write_smc_sram_dword(struct pp_smumgr *smumgr, - uint32_t smcAddress, uint32_t value, - uint32_t limit) -{ - int result; - - result = iceland_set_smc_sram_address(smumgr, smcAddress, limit); - - if (0 != result) - return result; - - cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, value); - - return 0; -} - -static int iceland_smu_fini(struct pp_smumgr *smumgr) -{ - struct iceland_smumgr *priv = (struct iceland_smumgr *)(smumgr->backend); - - smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); - - if (smumgr->backend != NULL) { - kfree(smumgr->backend); - smumgr->backend = NULL; - } - - cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); - return 0; -} - -static enum cgs_ucode_id iceland_convert_fw_type_to_cgs(uint32_t fw_type) -{ - enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM; - - switch (fw_type) { - case UCODE_ID_SMU: - result = CGS_UCODE_ID_SMU; - break; - case UCODE_ID_SDMA0: - result = CGS_UCODE_ID_SDMA0; - break; - case UCODE_ID_SDMA1: - result = CGS_UCODE_ID_SDMA1; - break; - case UCODE_ID_CP_CE: - result = CGS_UCODE_ID_CP_CE; - break; - case UCODE_ID_CP_PFP: - result = CGS_UCODE_ID_CP_PFP; - break; - case UCODE_ID_CP_ME: - result = CGS_UCODE_ID_CP_ME; - break; - case UCODE_ID_CP_MEC: - result = CGS_UCODE_ID_CP_MEC; - break; - case UCODE_ID_CP_MEC_JT1: - result = CGS_UCODE_ID_CP_MEC_JT1; - break; - case UCODE_ID_CP_MEC_JT2: - result = CGS_UCODE_ID_CP_MEC_JT2; - break; - case UCODE_ID_RLC_G: - result = CGS_UCODE_ID_RLC_G; - break; - default: - break; - } - - return result; -} - -/** - * Convert the PPIRI firmware type to SMU type mask. - * For MEC, we need to check all MEC related type - */ -static uint16_t iceland_get_mask_for_firmware_type(uint16_t firmwareType) -{ - uint16_t result = 0; - - switch (firmwareType) { - case UCODE_ID_SDMA0: - result = UCODE_ID_SDMA0_MASK; - break; - case UCODE_ID_SDMA1: - result = UCODE_ID_SDMA1_MASK; - break; - case UCODE_ID_CP_CE: - result = UCODE_ID_CP_CE_MASK; - break; - case UCODE_ID_CP_PFP: - result = UCODE_ID_CP_PFP_MASK; - break; - case UCODE_ID_CP_ME: - result = UCODE_ID_CP_ME_MASK; - break; - case UCODE_ID_CP_MEC: - case UCODE_ID_CP_MEC_JT1: - case UCODE_ID_CP_MEC_JT2: - result = UCODE_ID_CP_MEC_MASK; - break; - case UCODE_ID_RLC_G: - result = UCODE_ID_RLC_G_MASK; - break; - default: - break; - } - - return result; -} - -/** - * Check if the FW has been loaded, - * SMU will not return if loading has not finished. -*/ -static int iceland_check_fw_load_finish(struct pp_smumgr *smumgr, uint32_t fwType) -{ - uint16_t fwMask = iceland_get_mask_for_firmware_type(fwType); - - if (0 != SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, SMC_IND, - SOFT_REGISTERS_TABLE_27, fwMask, fwMask)) { - pr_err("[ powerplay ] check firmware loading failed\n"); - return -EINVAL; - } - - return 0; -} - -/* Populate one firmware image to the data structure */ -static int iceland_populate_single_firmware_entry(struct pp_smumgr *smumgr, - uint16_t firmware_type, - struct SMU_Entry *pentry) -{ - int result; - struct cgs_firmware_info info = {0}; - - result = cgs_get_firmware_info( - smumgr->device, - iceland_convert_fw_type_to_cgs(firmware_type), - &info); - - if (result == 0) { - pentry->version = 0; - pentry->id = (uint16_t)firmware_type; - pentry->image_addr_high = smu_upper_32_bits(info.mc_addr); - pentry->image_addr_low = smu_lower_32_bits(info.mc_addr); - pentry->meta_data_addr_high = 0; - pentry->meta_data_addr_low = 0; - pentry->data_size_byte = info.image_size; - pentry->num_register_entries = 0; - - if (firmware_type == UCODE_ID_RLC_G) - pentry->flags = 1; - else - pentry->flags = 0; - } else { - return result; - } - - return result; -} - -static void iceland_pp_stop_smc_clock(struct pp_smumgr *smumgr) +static void iceland_stop_smc_clock(struct pp_smumgr *smumgr) { SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, @@ -448,10 +68,10 @@ static void iceland_start_smc_clock(struct pp_smumgr *smumgr) ck_disable, 0); } -int iceland_smu_start_smc(struct pp_smumgr *smumgr) +static int iceland_smu_start_smc(struct pp_smumgr *smumgr) { /* set smc instruct start point at 0x0 */ - iceland_program_jump_on_start(smumgr); + smu7_program_jump_on_start(smumgr); /* enable smc clock */ iceland_start_smc_clock(smumgr); @@ -465,17 +85,37 @@ int iceland_smu_start_smc(struct pp_smumgr *smumgr) return 0; } -/** - * Upload the SMC firmware to the SMC microcontroller. - * - * @param smumgr the address of the powerplay hardware manager. - * @param pFirmware the data structure containing the various sections of the firmware. - */ -int iceland_smu_upload_firmware_image(struct pp_smumgr *smumgr) + +static int iceland_upload_smc_firmware_data(struct pp_smumgr *smumgr, + uint32_t length, const uint8_t *src, + uint32_t limit, uint32_t start_addr) { - const uint8_t *src; - uint32_t byte_count, val; + uint32_t byte_count = length; uint32_t data; + + PP_ASSERT_WITH_CODE((limit >= byte_count), "SMC address is beyond the SMC RAM area.", return -EINVAL); + + cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, start_addr); + SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1); + + while (byte_count >= 4) { + data = src[0] * 0x1000000 + src[1] * 0x10000 + src[2] * 0x100 + src[3]; + cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data); + src += 4; + byte_count -= 4; + } + + SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); + + PP_ASSERT_WITH_CODE((0 == byte_count), "SMC size must be dividable by 4.", return -EINVAL); + + return 0; +} + + +static int iceland_smu_upload_firmware_image(struct pp_smumgr *smumgr) +{ + uint32_t val; struct cgs_firmware_info info = {0}; if (smumgr == NULL || smumgr->device == NULL) @@ -483,7 +123,7 @@ int iceland_smu_upload_firmware_image(struct pp_smumgr *smumgr) /* load SMC firmware */ cgs_get_firmware_info(smumgr->device, - iceland_convert_fw_type_to_cgs(UCODE_ID_SMU), &info); + smu7_convert_fw_type_to_cgs(UCODE_ID_SMU), &info); if (info.image_size & 3) { pr_err("[ powerplay ] SMC ucode is not 4 bytes aligned\n"); @@ -506,122 +146,17 @@ int iceland_smu_upload_firmware_image(struct pp_smumgr *smumgr) ixSMC_SYSCON_MISC_CNTL, val | 1); /* stop smc clock */ - iceland_pp_stop_smc_clock(smumgr); + iceland_stop_smc_clock(smumgr); /* reset smc */ - iceland_pp_reset_smc(smumgr); - - cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, - info.ucode_start_address); - - SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, - AUTO_INCREMENT_IND_0, 1); - - byte_count = info.image_size; - src = (const uint8_t *)info.kptr; - - while (byte_count >= 4) { - data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3]; - cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data); - src += 4; - byte_count -= 4; - } - - SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, - AUTO_INCREMENT_IND_0, 0); + iceland_reset_smc(smumgr); + iceland_upload_smc_firmware_data(smumgr, info.image_size, + (uint8_t *)info.kptr, ICELAND_SMC_SIZE, + info.ucode_start_address); return 0; } -static int iceland_request_smu_reload_fw(struct pp_smumgr *smumgr) -{ - struct iceland_smumgr *iceland_smu = - (struct iceland_smumgr *)(smumgr->backend); - uint16_t fw_to_load; - int result = 0; - struct SMU_DRAMData_TOC *toc; - - toc = (struct SMU_DRAMData_TOC *)iceland_smu->pHeader; - toc->num_entries = 0; - toc->structure_version = 1; - - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry(smumgr, - UCODE_ID_RLC_G, - &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", - return -1); - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry(smumgr, - UCODE_ID_CP_CE, - &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", - return -1); - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry - (smumgr, UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", return -1); - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry - (smumgr, UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", return -1); - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry - (smumgr, UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", return -1); - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry - (smumgr, UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", return -1); - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry - (smumgr, UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", return -1); - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry - (smumgr, UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", return -1); - PP_ASSERT_WITH_CODE( - 0 == iceland_populate_single_firmware_entry - (smumgr, UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.\n", return -1); - - if (!iceland_is_smc_ram_running(smumgr)) { - result = iceland_smu_upload_firmware_image(smumgr); - if (result) - return result; - - result = iceland_smu_start_smc(smumgr); - if (result) - return result; - } - - iceland_send_msg_to_smc_with_parameter(smumgr, - PPSMC_MSG_DRV_DRAM_ADDR_HI, - iceland_smu->header_buffer.mc_addr_high); - - iceland_send_msg_to_smc_with_parameter(smumgr, - PPSMC_MSG_DRV_DRAM_ADDR_LO, - iceland_smu->header_buffer.mc_addr_low); - - fw_to_load = UCODE_ID_RLC_G_MASK - + UCODE_ID_SDMA0_MASK - + UCODE_ID_SDMA1_MASK - + UCODE_ID_CP_CE_MASK - + UCODE_ID_CP_ME_MASK - + UCODE_ID_CP_PFP_MASK - + UCODE_ID_CP_MEC_MASK - + UCODE_ID_CP_MEC_JT1_MASK - + UCODE_ID_CP_MEC_JT2_MASK; - - PP_ASSERT_WITH_CODE( - 0 == iceland_send_msg_to_smc_with_parameter( - smumgr, PPSMC_MSG_LoadUcodes, fw_to_load), - "Fail to Request SMU Load uCode", return 0); - - return result; -} - static int iceland_request_smu_load_specific_fw(struct pp_smumgr *smumgr, uint32_t firmwareType) { @@ -635,12 +170,22 @@ static int iceland_start_smu(struct pp_smumgr *smumgr) result = iceland_smu_upload_firmware_image(smumgr); if (result) return result; - result = iceland_smu_start_smc(smumgr); if (result) return result; - result = iceland_request_smu_reload_fw(smumgr); + if (!smu7_is_smc_ram_running(smumgr)) { + printk("smu not running, upload firmware again \n"); + result = iceland_smu_upload_firmware_image(smumgr); + if (result) + return result; + + result = iceland_smu_start_smc(smumgr); + if (result) + return result; + } + + result = smu7_request_smu_load_fw(smumgr); return result; } @@ -654,45 +199,18 @@ static int iceland_start_smu(struct pp_smumgr *smumgr) */ static int iceland_smu_init(struct pp_smumgr *smumgr) { - struct iceland_smumgr *iceland_smu; - uint64_t mc_addr = 0; - - /* Allocate memory for backend private data */ - iceland_smu = (struct iceland_smumgr *)(smumgr->backend); - iceland_smu->header_buffer.data_size = - ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096; - - smu_allocate_memory(smumgr->device, - iceland_smu->header_buffer.data_size, - CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB, - PAGE_SIZE, - &mc_addr, - &iceland_smu->header_buffer.kaddr, - &iceland_smu->header_buffer.handle); - - iceland_smu->pHeader = iceland_smu->header_buffer.kaddr; - iceland_smu->header_buffer.mc_addr_high = smu_upper_32_bits(mc_addr); - iceland_smu->header_buffer.mc_addr_low = smu_lower_32_bits(mc_addr); - - PP_ASSERT_WITH_CODE((NULL != iceland_smu->pHeader), - "Out of memory.", - kfree(smumgr->backend); - cgs_free_gpu_mem(smumgr->device, - (cgs_handle_t)iceland_smu->header_buffer.handle); - return -1); - - return 0; + return smu7_init(smumgr); } static const struct pp_smumgr_func iceland_smu_funcs = { .smu_init = &iceland_smu_init, - .smu_fini = &iceland_smu_fini, + .smu_fini = &smu7_smu_fini, .start_smu = &iceland_start_smu, - .check_fw_load_finish = &iceland_check_fw_load_finish, - .request_smu_load_fw = &iceland_request_smu_reload_fw, + .check_fw_load_finish = &smu7_check_fw_load_finish, + .request_smu_load_fw = &smu7_reload_firmware, .request_smu_load_specific_fw = &iceland_request_smu_load_specific_fw, - .send_msg_to_smc = &iceland_send_msg_to_smc, - .send_msg_to_smc_with_parameter = &iceland_send_msg_to_smc_with_parameter, + .send_msg_to_smc = &smu7_send_msg_to_smc, + .send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter, .download_pptable_settings = NULL, .upload_pptable_settings = NULL, }; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.h index 62009a7ae827..331e2782e5b4 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.h @@ -26,39 +26,12 @@ #ifndef _ICELAND_SMUMGR_H_ #define _ICELAND_SMUMGR_H_ -struct iceland_buffer_entry { - uint32_t data_size; - uint32_t mc_addr_low; - uint32_t mc_addr_high; - void *kaddr; - unsigned long handle; -}; - -/* Iceland only has header_buffer, don't have smu buffer. */ -struct iceland_smumgr { - uint8_t *pHeader; - uint8_t *pMecImage; - uint32_t ulSoftRegsStart; - - struct iceland_buffer_entry header_buffer; -}; - -extern int iceland_smum_init(struct pp_smumgr *smumgr); -extern int iceland_copy_bytes_to_smc(struct pp_smumgr *smumgr, - uint32_t smcStartAddress, - const uint8_t *src, - uint32_t byteCount, uint32_t limit); -extern int iceland_smu_start_smc(struct pp_smumgr *smumgr); +#include "smu7_smumgr.h" -extern int iceland_read_smc_sram_dword(struct pp_smumgr *smumgr, - uint32_t smcAddress, - uint32_t *value, uint32_t limit); -extern int iceland_write_smc_sram_dword(struct pp_smumgr *smumgr, - uint32_t smcAddress, - uint32_t value, uint32_t limit); -extern bool iceland_is_smc_ram_running(struct pp_smumgr *smumgr); -extern int iceland_smu_upload_firmware_image(struct pp_smumgr *smumgr); +struct iceland_smumgr { + struct smu7_smumgr smu7_data; +}; #endif