diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 259 | 
1 files changed, 255 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index ca3350502618..ffa4c0d207db 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -115,11 +115,30 @@ void amdgpu_ucode_print_gfx_hdr(const struct common_firmware_header *hdr)  			  le32_to_cpu(gfx_hdr->ucode_feature_version));  		DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(gfx_hdr->jt_offset));  		DRM_DEBUG("jt_size: %u\n", le32_to_cpu(gfx_hdr->jt_size)); +	} else if (version_major == 2) { +		const struct gfx_firmware_header_v2_0 *gfx_hdr = +			container_of(hdr, struct gfx_firmware_header_v2_0, header); + +		DRM_DEBUG("ucode_feature_version: %u\n", +			  le32_to_cpu(gfx_hdr->ucode_feature_version));  	} else {  		DRM_ERROR("Unknown GFX ucode version: %u.%u\n", version_major, version_minor);  	}  } +void amdgpu_ucode_print_imu_hdr(const struct common_firmware_header *hdr) +{ +	uint16_t version_major = le16_to_cpu(hdr->header_version_major); +	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor); + +	DRM_DEBUG("IMU\n"); +	amdgpu_ucode_print_common_hdr(hdr); + +	if (version_major != 1) { +		DRM_ERROR("Unknown GFX ucode version: %u.%u\n", version_major, version_minor); +	} +} +  void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)  {  	uint16_t version_major = le16_to_cpu(hdr->header_version_major); @@ -238,6 +257,17 @@ void amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header *hdr)  				container_of(sdma_hdr, struct sdma_firmware_header_v1_1, v1_0);  			DRM_DEBUG("digest_size: %u\n", le32_to_cpu(sdma_v1_1_hdr->digest_size));  		} +	} else if (version_major == 2) { +		const struct sdma_firmware_header_v2_0 *sdma_hdr = +			container_of(hdr, struct sdma_firmware_header_v2_0, header); + +		DRM_DEBUG("ucode_feature_version: %u\n", +			  le32_to_cpu(sdma_hdr->ucode_feature_version)); +		DRM_DEBUG("ctx_jt_offset: %u\n", le32_to_cpu(sdma_hdr->ctx_jt_offset)); +		DRM_DEBUG("ctx_jt_size: %u\n", le32_to_cpu(sdma_hdr->ctx_jt_size)); +		DRM_DEBUG("ctl_ucode_offset: %u\n", le32_to_cpu(sdma_hdr->ctl_ucode_offset)); +		DRM_DEBUG("ctl_jt_offset: %u\n", le32_to_cpu(sdma_hdr->ctl_jt_offset)); +		DRM_DEBUG("ctl_jt_size: %u\n", le32_to_cpu(sdma_hdr->ctl_jt_size));  	} else {  		DRM_ERROR("Unknown SDMA ucode version: %u.%u\n",  			  version_major, version_minor); @@ -248,6 +278,8 @@ void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr)  {  	uint16_t version_major = le16_to_cpu(hdr->header_version_major);  	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor); +	uint32_t fw_index; +	const struct psp_fw_bin_desc *desc;  	DRM_DEBUG("PSP\n");  	amdgpu_ucode_print_common_hdr(hdr); @@ -312,6 +344,71 @@ void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr)  			DRM_DEBUG("spl_size_bytes: %u\n",  				  le32_to_cpu(psp_hdr_v1_3->spl.size_bytes));  		} +	} else if (version_major == 2) { +		const struct psp_firmware_header_v2_0 *psp_hdr_v2_0 = +			 container_of(hdr, struct psp_firmware_header_v2_0, header); +		for (fw_index = 0; fw_index < le32_to_cpu(psp_hdr_v2_0->psp_fw_bin_count); fw_index++) { +			desc = &(psp_hdr_v2_0->psp_fw_bin[fw_index]); +			switch (desc->fw_type) { +			case PSP_FW_TYPE_PSP_SOS: +				DRM_DEBUG("psp_sos_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_sos_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			case PSP_FW_TYPE_PSP_SYS_DRV: +				DRM_DEBUG("psp_sys_drv_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_sys_drv_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			case PSP_FW_TYPE_PSP_KDB: +				DRM_DEBUG("psp_kdb_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_kdb_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			case PSP_FW_TYPE_PSP_TOC: +				DRM_DEBUG("psp_toc_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_toc_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			case PSP_FW_TYPE_PSP_SPL: +				DRM_DEBUG("psp_spl_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_spl_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			case PSP_FW_TYPE_PSP_RL: +				DRM_DEBUG("psp_rl_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_rl_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			case PSP_FW_TYPE_PSP_SOC_DRV: +				DRM_DEBUG("psp_soc_drv_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_soc_drv_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			case PSP_FW_TYPE_PSP_INTF_DRV: +				DRM_DEBUG("psp_intf_drv_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_intf_drv_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			case PSP_FW_TYPE_PSP_DBG_DRV: +				DRM_DEBUG("psp_dbg_drv_version: %u\n", +					  le32_to_cpu(desc->fw_version)); +				DRM_DEBUG("psp_dbg_drv_size_bytes: %u\n", +					  le32_to_cpu(desc->size_bytes)); +				break; +			default: +				DRM_DEBUG("Unsupported PSP fw type: %d\n", desc->fw_type); +				break; +			} +		}  	} else {  		DRM_ERROR("Unknown PSP ucode version: %u.%u\n",  			  version_major, version_minor); @@ -355,8 +452,8 @@ bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr,  {  	if ((hdr->common.header_version_major == hdr_major) &&  		(hdr->common.header_version_minor == hdr_minor)) -		return false; -	return true; +		return true; +	return false;  }  enum amdgpu_firmware_load_type @@ -442,6 +539,10 @@ const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id)  		return "SDMA6";  	case AMDGPU_UCODE_ID_SDMA7:  		return "SDMA7"; +	case AMDGPU_UCODE_ID_SDMA_UCODE_TH0: +		return "SDMA_CTX"; +	case AMDGPU_UCODE_ID_SDMA_UCODE_TH1: +		return "SDMA_CTL";  	case AMDGPU_UCODE_ID_CP_CE:  		return "CP_CE";  	case AMDGPU_UCODE_ID_CP_PFP: @@ -460,6 +561,10 @@ const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id)  		return "CP_MES";  	case AMDGPU_UCODE_ID_CP_MES_DATA:  		return "CP_MES_DATA"; +	case AMDGPU_UCODE_ID_CP_MES1: +		return "CP_MES_KIQ"; +	case AMDGPU_UCODE_ID_CP_MES1_DATA: +		return "CP_MES_KIQ_DATA";  	case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL:  		return "RLC_RESTORE_LIST_CNTL";  	case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM: @@ -472,10 +577,20 @@ const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id)  		return "RLC_DRAM";  	case AMDGPU_UCODE_ID_RLC_G:  		return "RLC_G"; +	case AMDGPU_UCODE_ID_RLC_P: +		return "RLC_P"; +	case AMDGPU_UCODE_ID_RLC_V: +		return "RLC_V"; +	case AMDGPU_UCODE_ID_IMU_I: +		return "IMU_I"; +	case AMDGPU_UCODE_ID_IMU_D: +		return "IMU_D";  	case AMDGPU_UCODE_ID_STORAGE:  		return "STORAGE";  	case AMDGPU_UCODE_ID_SMC:  		return "SMC"; +	case AMDGPU_UCODE_ID_PPTABLE: +		return "PPTABLE";  	case AMDGPU_UCODE_ID_UVD:  		return "UVD";  	case AMDGPU_UCODE_ID_UVD1: @@ -570,9 +685,12 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,  {  	const struct common_firmware_header *header = NULL;  	const struct gfx_firmware_header_v1_0 *cp_hdr = NULL; +	const struct gfx_firmware_header_v2_0 *cpv2_hdr = NULL;  	const struct dmcu_firmware_header_v1_0 *dmcu_hdr = NULL;  	const struct dmcub_firmware_header_v1_0 *dmcub_hdr = NULL;  	const struct mes_firmware_header_v1_0 *mes_hdr = NULL; +	const struct sdma_firmware_header_v2_0 *sdma_hdr = NULL; +	const struct imu_firmware_header_v1_0 *imu_hdr = NULL;  	u8 *ucode_addr;  	if (NULL == ucode->fw) @@ -586,12 +704,25 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,  	header = (const struct common_firmware_header *)ucode->fw->data;  	cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; +	cpv2_hdr = (const struct gfx_firmware_header_v2_0 *)ucode->fw->data;  	dmcu_hdr = (const struct dmcu_firmware_header_v1_0 *)ucode->fw->data;  	dmcub_hdr = (const struct dmcub_firmware_header_v1_0 *)ucode->fw->data;  	mes_hdr = (const struct mes_firmware_header_v1_0 *)ucode->fw->data; +	sdma_hdr = (const struct sdma_firmware_header_v2_0 *)ucode->fw->data; +	imu_hdr = (const struct imu_firmware_header_v1_0 *)ucode->fw->data;  	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {  		switch (ucode->ucode_id) { +		case AMDGPU_UCODE_ID_SDMA_UCODE_TH0: +			ucode->ucode_size = le32_to_cpu(sdma_hdr->ctx_ucode_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(sdma_hdr->header.ucode_array_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_SDMA_UCODE_TH1: +			ucode->ucode_size = le32_to_cpu(sdma_hdr->ctl_ucode_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(sdma_hdr->ctl_ucode_offset); +			break;  		case AMDGPU_UCODE_ID_CP_MEC1:  		case AMDGPU_UCODE_ID_CP_MEC2:  			ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) - @@ -626,6 +757,14 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,  			ucode->ucode_size = adev->gfx.rlc.rlc_dram_ucode_size_bytes;  			ucode_addr = adev->gfx.rlc.rlc_dram_ucode;  			break; +		case AMDGPU_UCODE_ID_RLC_P: +			ucode->ucode_size = adev->gfx.rlc.rlcp_ucode_size_bytes; +			ucode_addr = adev->gfx.rlc.rlcp_ucode; +			break; +		case AMDGPU_UCODE_ID_RLC_V: +			ucode->ucode_size = adev->gfx.rlc.rlcv_ucode_size_bytes; +			ucode_addr = adev->gfx.rlc.rlcv_ucode; +			break;  		case AMDGPU_UCODE_ID_CP_MES:  			ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes);  			ucode_addr = (u8 *)ucode->fw->data + @@ -636,6 +775,16 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,  			ucode_addr = (u8 *)ucode->fw->data +  				le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes);  			break; +		case AMDGPU_UCODE_ID_CP_MES1: +			ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(mes_hdr->mes_ucode_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_MES1_DATA: +			ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes); +			break;  		case AMDGPU_UCODE_ID_DMCU_ERAM:  			ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) -  				le32_to_cpu(dmcu_hdr->intv_size_bytes); @@ -653,6 +802,76 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,  			ucode_addr = (u8 *)ucode->fw->data +  				le32_to_cpu(header->ucode_array_offset_bytes);  			break; +		case AMDGPU_UCODE_ID_PPTABLE: +			ucode->ucode_size = ucode->fw->size; +			ucode_addr = (u8 *)ucode->fw->data; +			break; +		case AMDGPU_UCODE_ID_IMU_I: +			ucode->ucode_size = le32_to_cpu(imu_hdr->imu_iram_ucode_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(imu_hdr->header.ucode_array_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_IMU_D: +			ucode->ucode_size = le32_to_cpu(imu_hdr->imu_dram_ucode_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(imu_hdr->header.ucode_array_offset_bytes) + +				le32_to_cpu(imu_hdr->imu_iram_ucode_size_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_PFP: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(header->ucode_array_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(cpv2_hdr->data_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(cpv2_hdr->data_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_ME: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(header->ucode_array_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(cpv2_hdr->data_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(cpv2_hdr->data_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_MEC: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(header->ucode_array_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(cpv2_hdr->data_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(cpv2_hdr->data_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(cpv2_hdr->data_offset_bytes); +			break; +		case AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK: +			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes); +			ucode_addr = (u8 *)ucode->fw->data + +				le32_to_cpu(cpv2_hdr->data_offset_bytes); +			break;  		default:  			ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);  			ucode_addr = (u8 *)ucode->fw->data + @@ -714,8 +933,7 @@ int amdgpu_ucode_create_bo(struct amdgpu_device *adev)  void amdgpu_ucode_free_bo(struct amdgpu_device *adev)  { -	if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) -		amdgpu_bo_free_kernel(&adev->firmware.fw_buf, +	amdgpu_bo_free_kernel(&adev->firmware.fw_buf,  		&adev->firmware.fw_buf_mc,  		&adev->firmware.fw_buf_ptr);  } @@ -760,3 +978,36 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)  	}  	return 0;  } + +void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, char *ucode_prefix, int len) +{ +	int maj, min, rev; +	char *ip_name; +	uint32_t version = adev->ip_versions[block_type][0]; + +	switch (block_type) { +	case GC_HWIP: +		ip_name = "gc"; +		break; +	case SDMA0_HWIP: +		ip_name = "sdma"; +		break; +	case MP0_HWIP: +		ip_name = "psp"; +		break; +	case MP1_HWIP: +		ip_name = "smu"; +		break; +	case UVD_HWIP: +		ip_name = "vcn"; +		break; +	default: +		BUG(); +	} + +	maj = IP_VERSION_MAJ(version); +	min = IP_VERSION_MIN(version); +	rev = IP_VERSION_REV(version); + +	snprintf(ucode_prefix, len, "%s_%d_%d_%d", ip_name, maj, min, rev); +}  |