drm/amdgpu: add save restore list cntl gpm and srm firmware support
RLC save/restore list cntl/gpm_mem/srm_mem ucodes are used for CGPG and gfxoff function. Signed-off-by: Huang Rui <ray.huang@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									d40e9b13c8
								
							
						
					
					
						commit
						621a6318ad
					
				| @ -774,9 +774,18 @@ struct amdgpu_rlc { | ||||
| 	u32 starting_offsets_start; | ||||
| 	u32 reg_list_format_size_bytes; | ||||
| 	u32 reg_list_size_bytes; | ||||
| 	u32 reg_list_format_direct_reg_list_length; | ||||
| 	u32 save_restore_list_cntl_size_bytes; | ||||
| 	u32 save_restore_list_gpm_size_bytes; | ||||
| 	u32 save_restore_list_srm_size_bytes; | ||||
| 
 | ||||
| 	u32 *register_list_format; | ||||
| 	u32 *register_restore; | ||||
| 	u8 *save_restore_list_cntl; | ||||
| 	u8 *save_restore_list_gpm; | ||||
| 	u8 *save_restore_list_srm; | ||||
| 
 | ||||
| 	bool is_rlc_v2_1; | ||||
| }; | ||||
| 
 | ||||
| #define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES | ||||
| @ -943,6 +952,12 @@ struct amdgpu_gfx { | ||||
| 	uint32_t			ce_feature_version; | ||||
| 	uint32_t			pfp_feature_version; | ||||
| 	uint32_t			rlc_feature_version; | ||||
| 	uint32_t			rlc_srlc_fw_version; | ||||
| 	uint32_t			rlc_srlc_feature_version; | ||||
| 	uint32_t			rlc_srlg_fw_version; | ||||
| 	uint32_t			rlc_srlg_feature_version; | ||||
| 	uint32_t			rlc_srls_fw_version; | ||||
| 	uint32_t			rlc_srls_feature_version; | ||||
| 	uint32_t			mec_feature_version; | ||||
| 	uint32_t			mec2_feature_version; | ||||
| 	struct amdgpu_ring		gfx_ring[AMDGPU_MAX_GFX_RINGS]; | ||||
|  | ||||
| @ -215,6 +215,18 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, | ||||
| 		fw_info->ver = adev->gfx.rlc_fw_version; | ||||
| 		fw_info->feature = adev->gfx.rlc_feature_version; | ||||
| 		break; | ||||
| 	case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL: | ||||
| 		fw_info->ver = adev->gfx.rlc_srlc_fw_version; | ||||
| 		fw_info->feature = adev->gfx.rlc_srlc_feature_version; | ||||
| 		break; | ||||
| 	case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM: | ||||
| 		fw_info->ver = adev->gfx.rlc_srlg_fw_version; | ||||
| 		fw_info->feature = adev->gfx.rlc_srlg_feature_version; | ||||
| 		break; | ||||
| 	case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM: | ||||
| 		fw_info->ver = adev->gfx.rlc_srls_fw_version; | ||||
| 		fw_info->feature = adev->gfx.rlc_srls_feature_version; | ||||
| 		break; | ||||
| 	case AMDGPU_INFO_FW_GFX_MEC: | ||||
| 		if (query_fw->index == 0) { | ||||
| 			fw_info->ver = adev->gfx.mec_fw_version; | ||||
| @ -1149,6 +1161,30 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data) | ||||
| 	seq_printf(m, "RLC feature version: %u, firmware version: 0x%08x\n", | ||||
| 		   fw_info.feature, fw_info.ver); | ||||
| 
 | ||||
| 	/* RLC SAVE RESTORE LIST CNTL */ | ||||
| 	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL; | ||||
| 	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	seq_printf(m, "RLC SRLC feature version: %u, firmware version: 0x%08x\n", | ||||
| 		   fw_info.feature, fw_info.ver); | ||||
| 
 | ||||
| 	/* RLC SAVE RESTORE LIST GPM MEM */ | ||||
| 	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM; | ||||
| 	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	seq_printf(m, "RLC SRLG feature version: %u, firmware version: 0x%08x\n", | ||||
| 		   fw_info.feature, fw_info.ver); | ||||
| 
 | ||||
| 	/* RLC SAVE RESTORE LIST SRM MEM */ | ||||
| 	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM; | ||||
| 	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	seq_printf(m, "RLC SRLS feature version: %u, firmware version: 0x%08x\n", | ||||
| 		   fw_info.feature, fw_info.ver); | ||||
| 
 | ||||
| 	/* MEC */ | ||||
| 	query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC; | ||||
| 	query_fw.index = 0; | ||||
|  | ||||
| @ -337,7 +337,10 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | ||||
| 	    (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 && | ||||
| 	     ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2 && | ||||
| 	     ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1_JT && | ||||
| 	     ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT)) { | ||||
| 	     ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT && | ||||
| 	     ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL && | ||||
| 	     ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM && | ||||
| 	     ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) { | ||||
| 		ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); | ||||
| 
 | ||||
| 		memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | ||||
| @ -359,6 +362,18 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | ||||
| 					      le32_to_cpu(header->ucode_array_offset_bytes) + | ||||
| 					      le32_to_cpu(cp_hdr->jt_offset) * 4), | ||||
| 		       ucode->ucode_size); | ||||
| 	} else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) { | ||||
| 		ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes; | ||||
| 		memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl, | ||||
| 		       ucode->ucode_size); | ||||
| 	} else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM) { | ||||
| 		ucode->ucode_size = adev->gfx.rlc.save_restore_list_gpm_size_bytes; | ||||
| 		memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_gpm, | ||||
| 		       ucode->ucode_size); | ||||
| 	} else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM) { | ||||
| 		ucode->ucode_size = adev->gfx.rlc.save_restore_list_srm_size_bytes; | ||||
| 		memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_srm, | ||||
| 		       ucode->ucode_size); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
|  | ||||
| @ -187,6 +187,9 @@ enum AMDGPU_UCODE_ID { | ||||
| 	AMDGPU_UCODE_ID_CP_MEC2, | ||||
| 	AMDGPU_UCODE_ID_CP_MEC2_JT, | ||||
| 	AMDGPU_UCODE_ID_RLC_G, | ||||
| 	AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL, | ||||
| 	AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM, | ||||
| 	AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM, | ||||
| 	AMDGPU_UCODE_ID_STORAGE, | ||||
| 	AMDGPU_UCODE_ID_SMC, | ||||
| 	AMDGPU_UCODE_ID_UVD, | ||||
|  | ||||
| @ -41,7 +41,6 @@ | ||||
| #define GFX9_MEC_HPD_SIZE 2048 | ||||
| #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L | ||||
| #define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L | ||||
| #define GFX9_RLC_FORMAT_DIRECT_REG_LIST_LENGTH 34 | ||||
| 
 | ||||
| #define mmPWR_MISC_CNTL_STATUS					0x0183 | ||||
| #define mmPWR_MISC_CNTL_STATUS_BASE_IDX				0 | ||||
| @ -401,6 +400,27 @@ static void gfx_v9_0_free_microcode(struct amdgpu_device *adev) | ||||
| 	kfree(adev->gfx.rlc.register_list_format); | ||||
| } | ||||
| 
 | ||||
| static void gfx_v9_0_init_rlc_ext_microcode(struct amdgpu_device *adev) | ||||
| { | ||||
| 	const struct rlc_firmware_header_v2_1 *rlc_hdr; | ||||
| 
 | ||||
| 	rlc_hdr = (const struct rlc_firmware_header_v2_1 *)adev->gfx.rlc_fw->data; | ||||
| 	adev->gfx.rlc_srlc_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_ucode_ver); | ||||
| 	adev->gfx.rlc_srlc_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_feature_ver); | ||||
| 	adev->gfx.rlc.save_restore_list_cntl_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_cntl_size_bytes); | ||||
| 	adev->gfx.rlc.save_restore_list_cntl = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_cntl_offset_bytes); | ||||
| 	adev->gfx.rlc_srlg_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_ucode_ver); | ||||
| 	adev->gfx.rlc_srlg_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_feature_ver); | ||||
| 	adev->gfx.rlc.save_restore_list_gpm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_gpm_size_bytes); | ||||
| 	adev->gfx.rlc.save_restore_list_gpm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_gpm_offset_bytes); | ||||
| 	adev->gfx.rlc_srls_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_ucode_ver); | ||||
| 	adev->gfx.rlc_srls_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_feature_ver); | ||||
| 	adev->gfx.rlc.save_restore_list_srm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_srm_size_bytes); | ||||
| 	adev->gfx.rlc.save_restore_list_srm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_srm_offset_bytes); | ||||
| 	adev->gfx.rlc.reg_list_format_direct_reg_list_length = | ||||
| 			le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length); | ||||
| } | ||||
| 
 | ||||
| static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) | ||||
| { | ||||
| 	const char *chip_name; | ||||
| @ -412,6 +432,8 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) | ||||
| 	const struct rlc_firmware_header_v2_0 *rlc_hdr; | ||||
| 	unsigned int *tmp = NULL; | ||||
| 	unsigned int i = 0; | ||||
| 	uint16_t version_major; | ||||
| 	uint16_t version_minor; | ||||
| 
 | ||||
| 	DRM_DEBUG("\n"); | ||||
| 
 | ||||
| @ -468,6 +490,12 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) | ||||
| 		goto out; | ||||
| 	err = amdgpu_ucode_validate(adev->gfx.rlc_fw); | ||||
| 	rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data; | ||||
| 
 | ||||
| 	version_major = le16_to_cpu(rlc_hdr->header.header_version_major); | ||||
| 	version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor); | ||||
| 	if (version_major == 2 && version_minor == 1) | ||||
| 		adev->gfx.rlc.is_rlc_v2_1 = true; | ||||
| 
 | ||||
| 	adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version); | ||||
| 	adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version); | ||||
| 	adev->gfx.rlc.save_and_restore_offset = | ||||
| @ -508,6 +536,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) | ||||
| 	for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++) | ||||
| 		adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]); | ||||
| 
 | ||||
| 	if (adev->gfx.rlc.is_rlc_v2_1) | ||||
| 		gfx_v9_0_init_rlc_ext_microcode(adev); | ||||
| 
 | ||||
| 	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); | ||||
| 	err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); | ||||
| 	if (err) | ||||
| @ -566,6 +597,26 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) | ||||
| 		adev->firmware.fw_size += | ||||
| 			ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); | ||||
| 
 | ||||
| 		if (adev->gfx.rlc.is_rlc_v2_1) { | ||||
| 			info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL]; | ||||
| 			info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL; | ||||
| 			info->fw = adev->gfx.rlc_fw; | ||||
| 			adev->firmware.fw_size += | ||||
| 				ALIGN(adev->gfx.rlc.save_restore_list_cntl_size_bytes, PAGE_SIZE); | ||||
| 
 | ||||
| 			info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM]; | ||||
| 			info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM; | ||||
| 			info->fw = adev->gfx.rlc_fw; | ||||
| 			adev->firmware.fw_size += | ||||
| 				ALIGN(adev->gfx.rlc.save_restore_list_gpm_size_bytes, PAGE_SIZE); | ||||
| 
 | ||||
| 			info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM]; | ||||
| 			info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM; | ||||
| 			info->fw = adev->gfx.rlc_fw; | ||||
| 			adev->firmware.fw_size += | ||||
| 				ALIGN(adev->gfx.rlc.save_restore_list_srm_size_bytes, PAGE_SIZE); | ||||
| 		} | ||||
| 
 | ||||
| 		info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1]; | ||||
| 		info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1; | ||||
| 		info->fw = adev->gfx.mec_fw; | ||||
| @ -1781,7 +1832,7 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev) | ||||
| 
 | ||||
| 	/* setup unique_indirect_regs array and indirect_start_offsets array */ | ||||
| 	gfx_v9_0_parse_ind_reg_list(register_list_format, | ||||
| 				GFX9_RLC_FORMAT_DIRECT_REG_LIST_LENGTH, | ||||
| 				adev->gfx.rlc.reg_list_format_direct_reg_list_length, | ||||
| 				adev->gfx.rlc.reg_list_format_size_bytes >> 2, | ||||
| 				unique_indirect_regs, | ||||
| 				&unique_indirect_reg_count, | ||||
|  | ||||
| @ -70,6 +70,15 @@ psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type * | ||||
| 	case AMDGPU_UCODE_ID_RLC_G: | ||||
| 		*type = GFX_FW_TYPE_RLC_G; | ||||
| 		break; | ||||
| 	case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL: | ||||
| 		*type = GFX_FW_TYPE_RLC_RESTORE_LIST_CNTL; | ||||
| 		break; | ||||
| 	case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM: | ||||
| 		*type = GFX_FW_TYPE_RLC_RESTORE_LIST_GPM_MEM; | ||||
| 		break; | ||||
| 	case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM: | ||||
| 		*type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_MEM; | ||||
| 		break; | ||||
| 	case AMDGPU_UCODE_ID_SMC: | ||||
| 		*type = GFX_FW_TYPE_SMU; | ||||
| 		break; | ||||
|  | ||||
| @ -630,6 +630,12 @@ struct drm_amdgpu_cs_chunk_data { | ||||
| 	#define AMDGPU_INFO_FW_ASD		0x0d | ||||
| 	/* Subquery id: Query VCN firmware version */ | ||||
| 	#define AMDGPU_INFO_FW_VCN		0x0e | ||||
| 	/* Subquery id: Query GFX RLC SRLC firmware version */ | ||||
| 	#define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL 0x0f | ||||
| 	/* Subquery id: Query GFX RLC SRLG firmware version */ | ||||
| 	#define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM 0x10 | ||||
| 	/* Subquery id: Query GFX RLC SRLS firmware version */ | ||||
| 	#define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM 0x11 | ||||
| /* number of bytes moved for TTM migration */ | ||||
| #define AMDGPU_INFO_NUM_BYTES_MOVED		0x0f | ||||
| /* the used VRAM size */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user