Export this interface for the AMDGPU_FW_LOAD_SMU type. gfx/sdma can request smu to load firmware. Split the smu7/8_start_smu function into two functions 1. start_smu, used for load smu firmware in smu7/8 and check smu firmware version. 2. request_smu_load_fw, used for load other ip's firmware on smu7/8 and add firmware loading staus check. v2: default fw loading type is via smu for VI, driver call smu to load all fw at the begin of hw init. Signed-off-by: Rex Zhu <Rex.Zhu@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/vi.c | 16 ++++++ drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 20 ++++---- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 4 +- .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c | 25 ++++----- .../drm/amd/powerplay/smumgr/polaris10_smumgr.c | 4 +- drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 59 +++++----------------- drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h | 3 +- drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | 46 ++++++++--------- .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c | 12 ++++- .../gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c | 4 +- 10 files changed, 86 insertions(+), 107 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 88b57a5..3384a15 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -1222,6 +1222,16 @@ static int vi_common_hw_init(void *handle) /* enable the doorbell aperture */ vi_enable_doorbell_aperture(adev, true); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) { + if (adev->powerplay.pp_funcs->load_firmware) { + amdgpu_ucode_init_bo(adev); + if (adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle)) { + adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT; + amdgpu_ucode_fini_bo(adev); + } + } + } + return 0; } @@ -1235,6 +1245,12 @@ static int vi_common_hw_fini(void *handle) if (amdgpu_sriov_vf(adev)) xgpu_vi_mailbox_put_irq(adev); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) { + release_firmware(adev->pm.fw); + adev->pm.fw = NULL; + amdgpu_ucode_fini_bo(adev); + } + return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index aff7c14..5dc8fb9 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -109,12 +109,6 @@ static int pp_sw_fini(void *handle) hwmgr_sw_fini(hwmgr); - if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) { - release_firmware(adev->pm.fw); - adev->pm.fw = NULL; - amdgpu_ucode_fini_bo(adev); - } - return 0; } @@ -124,9 +118,6 @@ static int pp_hw_init(void *handle) struct amdgpu_device *adev = handle; struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) - amdgpu_ucode_init_bo(adev); - ret = hwmgr_hw_init(hwmgr); if (ret) @@ -275,7 +266,16 @@ static int pp_set_clockgating_state(void *handle, static int pp_dpm_load_fw(void *handle) { - return 0; + struct pp_hwmgr *hwmgr = handle; + int ret = 0; + + if (!hwmgr || !hwmgr->smumgr_funcs) + return -EINVAL; + + if (hwmgr->smumgr_funcs->request_smu_load_fw) + ret = hwmgr->smumgr_funcs->request_smu_load_fw(hwmgr); + + return ret; } static int pp_dpm_fw_loading_complete(void *handle) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index b6b62a7..ffd7d78 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -310,8 +310,6 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr) offsetof(SMU73_Firmware_Header, SoftRegisters), &(priv->smu7_data.soft_regs_start), 0x40000); - result = smu7_request_smu_load_fw(hwmgr); - return result; } @@ -2643,7 +2641,7 @@ static int fiji_update_dpm_settings(struct pp_hwmgr *hwmgr, .smu_fini = &smu7_smu_fini, .start_smu = &fiji_start_smu, .check_fw_load_finish = &smu7_check_fw_load_finish, - .request_smu_load_fw = &smu7_reload_firmware, + .request_smu_load_fw = &smu7_request_smu_load_fw, .request_smu_load_specific_fw = NULL, .send_msg_to_smc = &smu7_send_msg_to_smc, .send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c index 73aa368..68a4836 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c @@ -232,27 +232,24 @@ static int iceland_request_smu_load_specific_fw(struct pp_hwmgr *hwmgr, static int iceland_start_smu(struct pp_hwmgr *hwmgr) { - int result; - - result = iceland_smu_upload_firmware_image(hwmgr); - if (result) - return result; - result = iceland_smu_start_smc(hwmgr); - if (result) - return result; + struct iceland_smumgr *priv = hwmgr->smu_backend; + int result = 0; if (!smu7_is_smc_ram_running(hwmgr)) { - pr_info("smu not running, upload firmware again \n"); result = iceland_smu_upload_firmware_image(hwmgr); if (result) return result; - result = iceland_smu_start_smc(hwmgr); - if (result) - return result; + iceland_smu_start_smc(hwmgr); } + /* Setup SoftRegsStart here for register lookup in case + * DummyBackEnd is used and ProcessFirmwareHeader is not executed + */ - result = smu7_request_smu_load_fw(hwmgr); + smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, SoftRegisters), + &(priv->smu7_data.soft_regs_start), 0x40000); return result; } @@ -2662,7 +2659,7 @@ static bool iceland_is_dpm_running(struct pp_hwmgr *hwmgr) .smu_fini = &smu7_smu_fini, .start_smu = &iceland_start_smu, .check_fw_load_finish = &smu7_check_fw_load_finish, - .request_smu_load_fw = &smu7_reload_firmware, + .request_smu_load_fw = &smu7_request_smu_load_fw, .request_smu_load_specific_fw = &iceland_request_smu_load_specific_fw, .send_msg_to_smc = &smu7_send_msg_to_smc, .send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index 872d382..2ad6ad9 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -313,8 +313,6 @@ static int polaris10_start_smu(struct pp_hwmgr *hwmgr) smu7_read_smc_sram_dword(hwmgr, SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, SoftRegisters), &(smu_data->smu7_data.soft_regs_start), 0x40000); - result = smu7_request_smu_load_fw(hwmgr); - return result; } @@ -2478,7 +2476,7 @@ static int polaris10_update_dpm_settings(struct pp_hwmgr *hwmgr, .smu_fini = smu7_smu_fini, .start_smu = polaris10_start_smu, .check_fw_load_finish = smu7_check_fw_load_finish, - .request_smu_load_fw = smu7_reload_firmware, + .request_smu_load_fw = smu7_request_smu_load_fw, .request_smu_load_specific_fw = NULL, .send_msg_to_smc = smu7_send_msg_to_smc, .send_msg_to_smc_with_parameter = smu7_send_msg_to_smc_with_parameter, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c index 10eb967..edfb061 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c @@ -302,44 +302,6 @@ int smu7_write_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_ return 0; } -/* Convert the firmware type to SMU type mask. For MEC, we need to check all MEC related type */ - -static uint32_t smu7_get_mask_for_firmware_type(uint32_t fw_type) -{ - uint32_t result = 0; - - switch (fw_type) { - 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: - pr_info("UCode type is out of range! \n"); - result = 0; - } - - return result; -} - static int smu7_populate_single_firmware_entry(struct pp_hwmgr *hwmgr, uint32_t fw_type, struct SMU_Entry *entry) @@ -381,6 +343,11 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) uint32_t fw_to_load; int r = 0; + if (hwmgr->smumgr_funcs->start_smu(hwmgr)) { + pr_err("smu not running \n"); + return -EINVAL; + } + if (smu_data->soft_regs_start) cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, smu_data->soft_regs_start + smum_get_offsetof(hwmgr, @@ -462,10 +429,13 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_HI, upper_32_bits(smu_data->header_buffer.mc_addr)); smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_LO, lower_32_bits(smu_data->header_buffer.mc_addr)); - if (smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_LoadUcodes, fw_to_load)) - pr_err("Fail to Request SMU Load uCode"); + smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_LoadUcodes, fw_to_load); - return r; + r = smu7_check_fw_load_finish(hwmgr, fw_to_load); + if (!r) + return 0; + + pr_err("SMU load firmware failed\n"); failed: kfree(smu_data->toc); @@ -477,20 +447,15 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) int smu7_check_fw_load_finish(struct pp_hwmgr *hwmgr, uint32_t fw_type) { struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); - uint32_t fw_mask = smu7_get_mask_for_firmware_type(fw_type); uint32_t ret; ret = phm_wait_on_indirect_register(hwmgr, mmSMC_IND_INDEX_11, smu_data->soft_regs_start + smum_get_offsetof(hwmgr, SMU_SoftRegisters, UcodeLoadStatus), - fw_mask, fw_mask); + fw_type, fw_type); return ret; } -int smu7_reload_firmware(struct pp_hwmgr *hwmgr) -{ - return hwmgr->smumgr_funcs->start_smu(hwmgr); -} static int smu7_upload_smc_firmware_data(struct pp_hwmgr *hwmgr, uint32_t length, uint32_t *src, uint32_t limit) { diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h index 01f0538f..10c8ceb 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h @@ -73,9 +73,8 @@ int smu7_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, int smu7_write_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t value, uint32_t limit); -int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr); int smu7_check_fw_load_finish(struct pp_hwmgr *hwmgr, uint32_t fw_type); -int smu7_reload_firmware(struct pp_hwmgr *hwmgr); +int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr); int smu7_upload_smu_firmware_image(struct pp_hwmgr *hwmgr); int smu7_init(struct pp_hwmgr *hwmgr); int smu7_smu_fini(struct pp_hwmgr *hwmgr); diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c index 7a4c425..90f5f30 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c @@ -658,6 +658,8 @@ static int smu8_request_smu_load_fw(struct pp_hwmgr *hwmgr) { struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; uint32_t smc_address; + uint32_t fw_to_check = 0; + int ret; smu8_smu_populate_firmware_entries(hwmgr); @@ -684,28 +686,9 @@ static int smu8_request_smu_load_fw(struct pp_hwmgr *hwmgr) smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob, smu8_smu->toc_entry_power_profiling_index); - return smu8_send_msg_to_smc_with_parameter(hwmgr, + smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob, smu8_smu->toc_entry_initialize_index); -} - -static int smu8_start_smu(struct pp_hwmgr *hwmgr) -{ - int ret = 0; - uint32_t fw_to_check = 0; - struct amdgpu_device *adev = hwmgr->adev; - - uint32_t index = SMN_MP1_SRAM_START_ADDR + - SMU8_FIRMWARE_HEADER_LOCATION + - offsetof(struct SMU8_Firmware_Header, Version); - - - if (hwmgr == NULL || hwmgr->device == NULL) - return -EINVAL; - - cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX, index); - hwmgr->smu_version = cgs_read_register(hwmgr->device, mmMP0PUB_IND_DATA); - adev->pm.fw_version = hwmgr->smu_version >> 8; fw_to_check = UCODE_ID_RLC_G_MASK | UCODE_ID_SDMA0_MASK | @@ -719,8 +702,6 @@ static int smu8_start_smu(struct pp_hwmgr *hwmgr) if (hwmgr->chip_id == CHIP_STONEY) fw_to_check &= ~(UCODE_ID_SDMA1_MASK | UCODE_ID_CP_MEC_JT2_MASK); - smu8_request_smu_load_fw(hwmgr); - ret = smu8_check_fw_load_finish(hwmgr, fw_to_check); if (ret) { pr_err("SMU firmware load failed\n"); @@ -734,6 +715,25 @@ static int smu8_start_smu(struct pp_hwmgr *hwmgr) return ret; } +static int smu8_start_smu(struct pp_hwmgr *hwmgr) +{ + struct amdgpu_device *adev = hwmgr->adev; + + uint32_t index = SMN_MP1_SRAM_START_ADDR + + SMU8_FIRMWARE_HEADER_LOCATION + + offsetof(struct SMU8_Firmware_Header, Version); + + + if (hwmgr == NULL || hwmgr->device == NULL) + return -EINVAL; + + cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX, index); + hwmgr->smu_version = cgs_read_register(hwmgr->device, mmMP0PUB_IND_DATA); + adev->pm.fw_version = hwmgr->smu_version >> 8; + + return 0; +} + static int smu8_smu_init(struct pp_hwmgr *hwmgr) { int ret = 0; @@ -876,7 +876,7 @@ static bool smu8_is_dpm_running(struct pp_hwmgr *hwmgr) .smu_fini = smu8_smu_fini, .start_smu = smu8_start_smu, .check_fw_load_finish = smu8_check_fw_load_finish, - .request_smu_load_fw = NULL, + .request_smu_load_fw = smu8_request_smu_load_fw, .request_smu_load_specific_fw = NULL, .get_argument = smu8_get_argument, .send_msg_to_smc = smu8_send_msg_to_smc, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c index ae8378e..d8f1ca2 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c @@ -192,7 +192,8 @@ static int tonga_start_in_non_protection_mode(struct pp_hwmgr *hwmgr) static int tonga_start_smu(struct pp_hwmgr *hwmgr) { - int result; + struct tonga_smumgr *priv = hwmgr->smu_backend; + int result = 0; /* Only start SMC if SMC RAM is not running */ if (!smu7_is_smc_ram_running(hwmgr) && hwmgr->not_vf) { @@ -209,7 +210,14 @@ static int tonga_start_smu(struct pp_hwmgr *hwmgr) } } - result = smu7_request_smu_load_fw(hwmgr); + /* Setup SoftRegsStart here for register lookup in case + * DummyBackEnd is used and ProcessFirmwareHeader is not executed + */ + + smu7_read_smc_sram_dword(hwmgr, + SMU72_FIRMWARE_HEADER_LOCATION + + offsetof(SMU72_Firmware_Header, SoftRegisters), + &(priv->smu7_data.soft_regs_start), 0x40000); return result; } diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c index 3d415fa..71e376f 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c @@ -218,8 +218,6 @@ static int vegam_start_smu(struct pp_hwmgr *hwmgr) &(smu_data->smu7_data.soft_regs_start), 0x40000); - result = smu7_request_smu_load_fw(hwmgr); - return result; } @@ -2280,7 +2278,7 @@ static int vegam_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) .smu_fini = smu7_smu_fini, .start_smu = vegam_start_smu, .check_fw_load_finish = smu7_check_fw_load_finish, - .request_smu_load_fw = smu7_reload_firmware, + .request_smu_load_fw = smu7_request_smu_load_fw, .request_smu_load_specific_fw = NULL, .send_msg_to_smc = smu7_send_msg_to_smc, .send_msg_to_smc_with_parameter = smu7_send_msg_to_smc_with_parameter, -- 1.9.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx