Commit e635ee07 authored by Huang Rui's avatar Huang Rui Committed by Alex Deucher

drm/amdgpu: use new flag to handle different firmware loading method

This patch introduces a new flag named "amdgpu_firmware_load_type" to
handle different firmware loading method. Since Vega10, there are
three ways to load firmware. It would be better to use a flag and a
fw_load_type kernel parameter to configure it.
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarHuang Rui <ray.huang@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 70170d14
...@@ -81,7 +81,7 @@ extern int amdgpu_pcie_gen2; ...@@ -81,7 +81,7 @@ extern int amdgpu_pcie_gen2;
extern int amdgpu_msi; extern int amdgpu_msi;
extern int amdgpu_lockup_timeout; extern int amdgpu_lockup_timeout;
extern int amdgpu_dpm; extern int amdgpu_dpm;
extern int amdgpu_smc_load_fw; extern int amdgpu_fw_load_type;
extern int amdgpu_aspm; extern int amdgpu_aspm;
extern int amdgpu_runtime_pm; extern int amdgpu_runtime_pm;
extern unsigned amdgpu_ip_block_mask; extern unsigned amdgpu_ip_block_mask;
...@@ -1063,9 +1063,15 @@ struct amdgpu_sdma { ...@@ -1063,9 +1063,15 @@ struct amdgpu_sdma {
/* /*
* Firmware * Firmware
*/ */
enum amdgpu_firmware_load_type {
AMDGPU_FW_LOAD_DIRECT = 0,
AMDGPU_FW_LOAD_SMU,
AMDGPU_FW_LOAD_PSP,
};
struct amdgpu_firmware { struct amdgpu_firmware {
struct amdgpu_firmware_info ucode[AMDGPU_UCODE_ID_MAXIMUM]; struct amdgpu_firmware_info ucode[AMDGPU_UCODE_ID_MAXIMUM];
bool smu_load; enum amdgpu_firmware_load_type load_type;
struct amdgpu_bo *fw_buf; struct amdgpu_bo *fw_buf;
unsigned int fw_size; unsigned int fw_size;
}; };
......
...@@ -80,7 +80,7 @@ int amdgpu_pcie_gen2 = -1; ...@@ -80,7 +80,7 @@ int amdgpu_pcie_gen2 = -1;
int amdgpu_msi = -1; int amdgpu_msi = -1;
int amdgpu_lockup_timeout = 0; int amdgpu_lockup_timeout = 0;
int amdgpu_dpm = -1; int amdgpu_dpm = -1;
int amdgpu_smc_load_fw = 1; int amdgpu_fw_load_type = -1;
int amdgpu_aspm = -1; int amdgpu_aspm = -1;
int amdgpu_runtime_pm = -1; int amdgpu_runtime_pm = -1;
unsigned amdgpu_ip_block_mask = 0xffffffff; unsigned amdgpu_ip_block_mask = 0xffffffff;
...@@ -140,8 +140,8 @@ module_param_named(lockup_timeout, amdgpu_lockup_timeout, int, 0444); ...@@ -140,8 +140,8 @@ module_param_named(lockup_timeout, amdgpu_lockup_timeout, int, 0444);
MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)"); MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)");
module_param_named(dpm, amdgpu_dpm, int, 0444); module_param_named(dpm, amdgpu_dpm, int, 0444);
MODULE_PARM_DESC(smc_load_fw, "SMC firmware loading(1 = enable, 0 = disable)"); MODULE_PARM_DESC(fw_load_type, "firmware loading type (0 = direct, 1 = SMU, 2 = PSP, -1 = auto)");
module_param_named(smc_load_fw, amdgpu_smc_load_fw, int, 0444); module_param_named(fw_load_type, amdgpu_fw_load_type, int, 0444);
MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)"); MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)");
module_param_named(aspm, amdgpu_aspm, int, 0444); module_param_named(aspm, amdgpu_aspm, int, 0444);
......
...@@ -163,7 +163,7 @@ static int amdgpu_pp_hw_init(void *handle) ...@@ -163,7 +163,7 @@ static int amdgpu_pp_hw_init(void *handle)
int ret = 0; int ret = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->pp_enabled && adev->firmware.smu_load) if (adev->pp_enabled && adev->firmware.load_type == AMDGPU_FW_LOAD_SMU)
amdgpu_ucode_init_bo(adev); amdgpu_ucode_init_bo(adev);
if (adev->powerplay.ip_funcs->hw_init) if (adev->powerplay.ip_funcs->hw_init)
...@@ -190,7 +190,7 @@ static int amdgpu_pp_hw_fini(void *handle) ...@@ -190,7 +190,7 @@ static int amdgpu_pp_hw_fini(void *handle)
ret = adev->powerplay.ip_funcs->hw_fini( ret = adev->powerplay.ip_funcs->hw_fini(
adev->powerplay.pp_handle); adev->powerplay.pp_handle);
if (adev->pp_enabled && adev->firmware.smu_load) if (adev->pp_enabled && adev->firmware.load_type == AMDGPU_FW_LOAD_SMU)
amdgpu_ucode_fini_bo(adev); amdgpu_ucode_fini_bo(adev);
return ret; return ret;
......
...@@ -217,6 +217,49 @@ bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr, ...@@ -217,6 +217,49 @@ bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr,
return true; return true;
} }
enum amdgpu_firmware_load_type
amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
{
switch (adev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_SI
case CHIP_TAHITI:
case CHIP_PITCAIRN:
case CHIP_VERDE:
case CHIP_OLAND:
return AMDGPU_FW_LOAD_DIRECT;
#endif
#ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_BONAIRE:
case CHIP_KAVERI:
case CHIP_KABINI:
case CHIP_HAWAII:
case CHIP_MULLINS:
return AMDGPU_FW_LOAD_DIRECT;
#endif
case CHIP_TOPAZ:
case CHIP_TONGA:
case CHIP_FIJI:
case CHIP_CARRIZO:
case CHIP_STONEY:
case CHIP_POLARIS10:
case CHIP_POLARIS11:
case CHIP_POLARIS12:
if (!load_type)
return AMDGPU_FW_LOAD_DIRECT;
else
return AMDGPU_FW_LOAD_SMU;
case CHIP_VEGA10:
if (!load_type)
return AMDGPU_FW_LOAD_DIRECT;
else
return AMDGPU_FW_LOAD_PSP;
default:
DRM_ERROR("Unknow firmware load type\n");
}
return AMDGPU_FW_LOAD_DIRECT;
}
static int amdgpu_ucode_init_single_fw(struct amdgpu_firmware_info *ucode, static int amdgpu_ucode_init_single_fw(struct amdgpu_firmware_info *ucode,
uint64_t mc_addr, void *kptr) uint64_t mc_addr, void *kptr)
{ {
...@@ -273,7 +316,7 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) ...@@ -273,7 +316,7 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
uint64_t fw_mc_addr; uint64_t fw_mc_addr;
void *fw_buf_ptr = NULL; void *fw_buf_ptr = NULL;
uint64_t fw_offset = 0; uint64_t fw_offset = 0;
int i, err; int i, err, max;
struct amdgpu_firmware_info *ucode = NULL; struct amdgpu_firmware_info *ucode = NULL;
const struct common_firmware_header *header = NULL; const struct common_firmware_header *header = NULL;
...@@ -306,7 +349,16 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) ...@@ -306,7 +349,16 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
amdgpu_bo_unreserve(*bo); amdgpu_bo_unreserve(*bo);
for (i = 0; i < AMDGPU_UCODE_ID_MAXIMUM; i++) { /*
* if SMU loaded firmware, it needn't add SMC, UVD, and VCE
* ucode info here
*/
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
max = AMDGPU_UCODE_ID_MAXIMUM - 3;
else
max = AMDGPU_UCODE_ID_MAXIMUM;
for (i = 0; i < max; i++) {
ucode = &adev->firmware.ucode[i]; ucode = &adev->firmware.ucode[i];
if (ucode->fw) { if (ucode->fw) {
header = (const struct common_firmware_header *)ucode->fw->data; header = (const struct common_firmware_header *)ucode->fw->data;
...@@ -331,7 +383,8 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) ...@@ -331,7 +383,8 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
failed_reserve: failed_reserve:
amdgpu_bo_unref(bo); amdgpu_bo_unref(bo);
failed: failed:
adev->firmware.smu_load = false; if (err)
adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT;
return err; return err;
} }
...@@ -340,8 +393,14 @@ int amdgpu_ucode_fini_bo(struct amdgpu_device *adev) ...@@ -340,8 +393,14 @@ int amdgpu_ucode_fini_bo(struct amdgpu_device *adev)
{ {
int i; int i;
struct amdgpu_firmware_info *ucode = NULL; struct amdgpu_firmware_info *ucode = NULL;
int max;
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
max = AMDGPU_UCODE_ID_MAXIMUM - 3;
else
max = AMDGPU_UCODE_ID_MAXIMUM;
for (i = 0; i < AMDGPU_UCODE_ID_MAXIMUM; i++) { for (i = 0; i < max; i++) {
ucode = &adev->firmware.ucode[i]; ucode = &adev->firmware.ucode[i];
if (ucode->fw) { if (ucode->fw) {
ucode->mc_addr = 0; ucode->mc_addr = 0;
......
...@@ -176,4 +176,7 @@ bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr, ...@@ -176,4 +176,7 @@ bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr,
int amdgpu_ucode_init_bo(struct amdgpu_device *adev); int amdgpu_ucode_init_bo(struct amdgpu_device *adev);
int amdgpu_ucode_fini_bo(struct amdgpu_device *adev); int amdgpu_ucode_fini_bo(struct amdgpu_device *adev);
enum amdgpu_firmware_load_type
amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type);
#endif #endif
...@@ -1785,6 +1785,8 @@ static int cik_common_early_init(void *handle) ...@@ -1785,6 +1785,8 @@ static int cik_common_early_init(void *handle)
return -EINVAL; return -EINVAL;
} }
adev->firmware.load_type = amdgpu_ucode_get_load_type(adev, amdgpu_fw_load_type);
amdgpu_get_pcie_info(adev); amdgpu_get_pcie_info(adev);
return 0; return 0;
......
...@@ -1040,7 +1040,7 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) ...@@ -1040,7 +1040,7 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev)
} }
} }
if (adev->firmware.smu_load) { if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_PFP]; info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_PFP];
info->ucode_id = AMDGPU_UCODE_ID_CP_PFP; info->ucode_id = AMDGPU_UCODE_ID_CP_PFP;
info->fw = adev->gfx.pfp_fw; info->fw = adev->gfx.pfp_fw;
...@@ -4253,7 +4253,7 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev) ...@@ -4253,7 +4253,7 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
gfx_v8_0_init_pg(adev); gfx_v8_0_init_pg(adev);
if (!adev->pp_enabled) { if (!adev->pp_enabled) {
if (!adev->firmware.smu_load) { if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) {
/* legacy rlc firmware loading */ /* legacy rlc firmware loading */
r = gfx_v8_0_rlc_load_microcode(adev); r = gfx_v8_0_rlc_load_microcode(adev);
if (r) if (r)
...@@ -5269,7 +5269,7 @@ static int gfx_v8_0_cp_resume(struct amdgpu_device *adev) ...@@ -5269,7 +5269,7 @@ static int gfx_v8_0_cp_resume(struct amdgpu_device *adev)
gfx_v8_0_enable_gui_idle_interrupt(adev, false); gfx_v8_0_enable_gui_idle_interrupt(adev, false);
if (!adev->pp_enabled) { if (!adev->pp_enabled) {
if (!adev->firmware.smu_load) { if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) {
/* legacy firmware loading */ /* legacy firmware loading */
r = gfx_v8_0_cp_gfx_load_microcode(adev); r = gfx_v8_0_cp_gfx_load_microcode(adev);
if (r) if (r)
......
...@@ -158,7 +158,7 @@ static int sdma_v2_4_init_microcode(struct amdgpu_device *adev) ...@@ -158,7 +158,7 @@ static int sdma_v2_4_init_microcode(struct amdgpu_device *adev)
if (adev->sdma.instance[i].feature_version >= 20) if (adev->sdma.instance[i].feature_version >= 20)
adev->sdma.instance[i].burst_nop = true; adev->sdma.instance[i].burst_nop = true;
if (adev->firmware.smu_load) { if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i]; info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i; info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
info->fw = adev->sdma.instance[i].fw; info->fw = adev->sdma.instance[i].fw;
...@@ -562,7 +562,7 @@ static int sdma_v2_4_start(struct amdgpu_device *adev) ...@@ -562,7 +562,7 @@ static int sdma_v2_4_start(struct amdgpu_device *adev)
int r; int r;
if (!adev->pp_enabled) { if (!adev->pp_enabled) {
if (!adev->firmware.smu_load) { if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) {
r = sdma_v2_4_load_microcode(adev); r = sdma_v2_4_load_microcode(adev);
if (r) if (r)
return r; return r;
......
...@@ -310,7 +310,7 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev) ...@@ -310,7 +310,7 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev)
if (adev->sdma.instance[i].feature_version >= 20) if (adev->sdma.instance[i].feature_version >= 20)
adev->sdma.instance[i].burst_nop = true; adev->sdma.instance[i].burst_nop = true;
if (adev->firmware.smu_load) { if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i]; info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i; info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
info->fw = adev->sdma.instance[i].fw; info->fw = adev->sdma.instance[i].fw;
...@@ -771,7 +771,7 @@ static int sdma_v3_0_start(struct amdgpu_device *adev) ...@@ -771,7 +771,7 @@ static int sdma_v3_0_start(struct amdgpu_device *adev)
int r, i; int r, i;
if (!adev->pp_enabled) { if (!adev->pp_enabled) {
if (!adev->firmware.smu_load) { if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) {
r = sdma_v3_0_load_microcode(adev); r = sdma_v3_0_load_microcode(adev);
if (r) if (r)
return r; return r;
......
...@@ -1117,8 +1117,8 @@ static int vi_common_early_init(void *handle) ...@@ -1117,8 +1117,8 @@ static int vi_common_early_init(void *handle)
return -EINVAL; return -EINVAL;
} }
if (amdgpu_smc_load_fw && smc_enabled) /* vi use smc load by default */
adev->firmware.smu_load = true; adev->firmware.load_type = amdgpu_ucode_get_load_type(adev, amdgpu_fw_load_type);
amdgpu_get_pcie_info(adev); amdgpu_get_pcie_info(adev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment