[PATCH 1/2] drm/amd/pp: Export load_firmware interface

Rex Zhu Rex.Zhu at amd.com
Fri Sep 28 09:43:55 UTC 2018


Export this interface for the AMDGPU_FW_LOAD_SMU type.
This interface only be supported on VI. and gfx/sdma's
firmware will be loaded together by smu.
so in AMDGPU_FW_LOAD_SMU mode, the gfx and sdma ip
can't be disabled by module parameter.

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: release ucode bo when gfx hw fini.

Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c              | 17 ++++++-
 drivers/gpu/drm/amd/powerplay/amd_powerplay.c      | 23 +++++----
 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, 87 insertions(+), 110 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index 2aeef2b..12609f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -955,7 +955,11 @@ static void gfx_v8_0_free_microcode(struct amdgpu_device *adev)
 		release_firmware(adev->gfx.mec2_fw);
 	adev->gfx.mec2_fw = NULL;
 
+	if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU)
+		amdgpu_ucode_fini_bo(adev);
+
 	kfree(adev->gfx.rlc.register_list_format);
+
 }
 
 static int gfx_v8_0_init_microcode(struct amdgpu_device *adev)
@@ -4216,10 +4220,19 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
 		/* legacy rlc firmware loading */
 		r = gfx_v8_0_rlc_load_microcode(adev);
-		if (r)
-			return r;
+	} else if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU &&
+		  adev->powerplay.pp_funcs->load_firmware) {
+		if (!adev->gfx.in_suspend)
+			amdgpu_ucode_init_bo(adev);
+		r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle);
+	} else {
+		r = -EINVAL;
 	}
 
+	if (r) {
+		pr_info("firmware loading failed\n");
+		return r;
+	}
 	gfx_v8_0_rlc_start(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..2e37033 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -108,13 +108,8 @@ static int pp_sw_fini(void *handle)
 	struct pp_hwmgr *hwmgr = adev->powerplay.pp_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);
-	}
-
+	release_firmware(adev->pm.fw);
+	adev->pm.fw = NULL;
 	return 0;
 }
 
@@ -124,9 +119,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 +267,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..7e819fa 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



More information about the amd-gfx mailing list