Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ extern int amdgpu_pcie_gen2;
extern int amdgpu_msi;
extern int amdgpu_lockup_timeout;
extern int amdgpu_dpm;
extern int amdgpu_smc_load_fw;
extern int amdgpu_fw_load_type;
extern int amdgpu_aspm;
extern int amdgpu_runtime_pm;
extern unsigned amdgpu_ip_block_mask;
@@ -1063,9 +1063,15 @@ struct amdgpu_sdma {
/*
 * 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_info ucode[AMDGPU_UCODE_ID_MAXIMUM];
	bool smu_load;
	enum amdgpu_firmware_load_type load_type;
	struct amdgpu_bo *fw_buf;
	unsigned int fw_size;
};
+3 −3
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ int amdgpu_pcie_gen2 = -1;
int amdgpu_msi = -1;
int amdgpu_lockup_timeout = 0;
int amdgpu_dpm = -1;
int amdgpu_smc_load_fw = 1;
int amdgpu_fw_load_type = -1;
int amdgpu_aspm = -1;
int amdgpu_runtime_pm = -1;
unsigned amdgpu_ip_block_mask = 0xffffffff;
@@ -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_param_named(dpm, amdgpu_dpm, int, 0444);

MODULE_PARM_DESC(smc_load_fw, "SMC firmware loading(1 = enable, 0 = disable)");
module_param_named(smc_load_fw, amdgpu_smc_load_fw, int, 0444);
MODULE_PARM_DESC(fw_load_type, "firmware loading type (0 = direct, 1 = SMU, 2 = PSP, -1 = auto)");
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_param_named(aspm, amdgpu_aspm, int, 0444);
+2 −2
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ static int amdgpu_pp_hw_init(void *handle)
	int ret = 0;
	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);

	if (adev->powerplay.ip_funcs->hw_init)
@@ -190,7 +190,7 @@ static int amdgpu_pp_hw_fini(void *handle)
		ret = adev->powerplay.ip_funcs->hw_fini(
					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);

	return ret;
+63 −4
Original line number Diff line number Diff line
@@ -217,6 +217,49 @@ bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr,
	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,
				uint64_t mc_addr, void *kptr)
{
@@ -273,7 +316,7 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
	uint64_t fw_mc_addr;
	void *fw_buf_ptr = NULL;
	uint64_t fw_offset = 0;
	int i, err;
	int i, err, max;
	struct amdgpu_firmware_info *ucode = NULL;
	const struct common_firmware_header *header = NULL;

@@ -306,7 +349,16 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)

	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];
		if (ucode->fw) {
			header = (const struct common_firmware_header *)ucode->fw->data;
@@ -331,7 +383,8 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
failed_reserve:
	amdgpu_bo_unref(bo);
failed:
	adev->firmware.smu_load = false;
	if (err)
		adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT;

	return err;
}
@@ -340,8 +393,14 @@ int amdgpu_ucode_fini_bo(struct amdgpu_device *adev)
{
	int i;
	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];
		if (ucode->fw) {
			ucode->mc_addr = 0;
+3 −0
Original line number Diff line number Diff line
@@ -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_fini_bo(struct amdgpu_device *adev);

enum amdgpu_firmware_load_type
amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type);

#endif
Loading