diff options
| author | Dmitry Torokhov <[email protected]> | 2024-07-15 14:03:44 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2024-07-15 14:03:44 -0700 | 
| commit | a23e1966932464e1c5226cb9ac4ce1d5fc10ba22 (patch) | |
| tree | bf5f1b57faa01ca31656bfc48c7d6b6f0bc39189 /drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | |
| parent | 7c7b1be19b228b450c2945ec379d7fc6bfef9852 (diff) | |
| parent | f3efefb6fdcce604413135bd8d4c5568e53a1f13 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.11 merge window.
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 81 | 
1 files changed, 61 insertions, 20 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index ae455aab5d29..9c514a606a2f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -58,6 +58,10 @@  #define FIRMWARE_VCN4_0_2		"amdgpu/vcn_4_0_2.bin"  #define FIRMWARE_VCN4_0_3		"amdgpu/vcn_4_0_3.bin"  #define FIRMWARE_VCN4_0_4		"amdgpu/vcn_4_0_4.bin" +#define FIRMWARE_VCN4_0_5		"amdgpu/vcn_4_0_5.bin" +#define FIRMWARE_VCN4_0_6		"amdgpu/vcn_4_0_6.bin" +#define FIRMWARE_VCN4_0_6_1		"amdgpu/vcn_4_0_6_1.bin" +#define FIRMWARE_VCN5_0_0		"amdgpu/vcn_5_0_0.bin"  MODULE_FIRMWARE(FIRMWARE_RAVEN);  MODULE_FIRMWARE(FIRMWARE_PICASSO); @@ -80,6 +84,10 @@ MODULE_FIRMWARE(FIRMWARE_VCN4_0_0);  MODULE_FIRMWARE(FIRMWARE_VCN4_0_2);  MODULE_FIRMWARE(FIRMWARE_VCN4_0_3);  MODULE_FIRMWARE(FIRMWARE_VCN4_0_4); +MODULE_FIRMWARE(FIRMWARE_VCN4_0_5); +MODULE_FIRMWARE(FIRMWARE_VCN4_0_6); +MODULE_FIRMWARE(FIRMWARE_VCN4_0_6_1); +MODULE_FIRMWARE(FIRMWARE_VCN5_0_0);  static void amdgpu_vcn_idle_work_handler(struct work_struct *work); @@ -87,14 +95,22 @@ int amdgpu_vcn_early_init(struct amdgpu_device *adev)  {  	char ucode_prefix[30];  	char fw_name[40]; -	int r; +	int r, i; -	amdgpu_ucode_ip_version_decode(adev, UVD_HWIP, ucode_prefix, sizeof(ucode_prefix)); -	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); -	r = amdgpu_ucode_request(adev, &adev->vcn.fw, fw_name); -	if (r) -		amdgpu_ucode_release(&adev->vcn.fw); +	for (i = 0; i < adev->vcn.num_vcn_inst; i++) { +		amdgpu_ucode_ip_version_decode(adev, UVD_HWIP, ucode_prefix, sizeof(ucode_prefix)); +		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); +		if (amdgpu_ip_version(adev, UVD_HWIP, 0) ==  IP_VERSION(4, 0, 6) && +			i == 1) { +			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_%d.bin", ucode_prefix, i); +		} +		r = amdgpu_ucode_request(adev, &adev->vcn.fw[i], fw_name); +		if (r) { +			amdgpu_ucode_release(&adev->vcn.fw[i]); +			return r; +		} +	}  	return r;  } @@ -124,7 +140,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)  	 * Hence, check for these versions here - notice this is  	 * restricted to Vangogh (Deck's APU).  	 */ -	if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(3, 0, 2)) { +	if (amdgpu_ip_version(adev, UVD_HWIP, 0) == IP_VERSION(3, 0, 2)) {  		const char *bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);  		if (bios_ver && (!strncmp("F7A0113", bios_ver, 7) || @@ -135,7 +151,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)  		}  	} -	hdr = (const struct common_firmware_header *)adev->vcn.fw->data; +	hdr = (const struct common_firmware_header *)adev->vcn.fw[0]->data;  	adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);  	/* Bit 20-23, it is encode major and non-zero for new naming convention. @@ -169,7 +185,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)  	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)  		bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); -	if (adev->ip_versions[UVD_HWIP][0] >= IP_VERSION(4, 0, 0)) { +	if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0)) {  		fw_shared_size = AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared));  		log_offset = offsetof(struct amdgpu_vcn4_fw_shared, fw_log);  	} else { @@ -250,9 +266,10 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)  		for (i = 0; i < adev->vcn.num_enc_rings; ++i)  			amdgpu_ring_fini(&adev->vcn.inst[j].ring_enc[i]); + +		amdgpu_ucode_release(&adev->vcn.fw[j]);  	} -	amdgpu_ucode_release(&adev->vcn.fw);  	mutex_destroy(&adev->vcn.vcn1_jpeg1_workaround);  	mutex_destroy(&adev->vcn.vcn_pg_lock); @@ -265,7 +282,7 @@ static bool amdgpu_vcn_using_unified_queue(struct amdgpu_ring *ring)  	struct amdgpu_device *adev = ring->adev;  	bool ret = false; -	if (adev->ip_versions[UVD_HWIP][0] >= IP_VERSION(4, 0, 0)) +	if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0))  		ret = true;  	return ret; @@ -292,8 +309,15 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)  	void *ptr;  	int i, idx; +	bool in_ras_intr = amdgpu_ras_intr_triggered(); +  	cancel_delayed_work_sync(&adev->vcn.idle_work); +	/* err_event_athub will corrupt VCPU buffer, so we need to +	 * restore fw data and clear buffer in amdgpu_vcn_resume() */ +	if (in_ras_intr) +		return 0; +  	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {  		if (adev->vcn.harvest_config & (1 << i))  			continue; @@ -341,11 +365,12 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)  			const struct common_firmware_header *hdr;  			unsigned int offset; -			hdr = (const struct common_firmware_header *)adev->vcn.fw->data; +			hdr = (const struct common_firmware_header *)adev->vcn.fw[i]->data;  			if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {  				offset = le32_to_cpu(hdr->ucode_array_offset_bytes);  				if (drm_dev_enter(adev_to_drm(adev), &idx)) { -					memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset, +					memcpy_toio(adev->vcn.inst[i].cpu_addr, +						    adev->vcn.fw[i]->data + offset,  						    le32_to_cpu(hdr->ucode_size_bytes));  					drm_dev_exit(idx);  				} @@ -996,7 +1021,7 @@ int amdgpu_vcn_unified_ring_test_ib(struct amdgpu_ring *ring, long timeout)  	struct amdgpu_device *adev = ring->adev;  	long r; -	if (adev->ip_versions[UVD_HWIP][0] != IP_VERSION(4, 0, 3)) { +	if (amdgpu_ip_version(adev, UVD_HWIP, 0) != IP_VERSION(4, 0, 3)) {  		r = amdgpu_vcn_enc_ring_test_ib(ring, timeout);  		if (r)  			goto error; @@ -1030,11 +1055,11 @@ void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev)  	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {  		const struct common_firmware_header *hdr; -		hdr = (const struct common_firmware_header *)adev->vcn.fw->data; -  		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {  			if (adev->vcn.harvest_config & (1 << i))  				continue; + +			hdr = (const struct common_firmware_header *)adev->vcn.fw[i]->data;  			/* currently only support 2 FW instances */  			if (i >= 2) {  				dev_info(adev->dev, "More then 2 VCN FW instances!\n"); @@ -1042,11 +1067,12 @@ void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev)  			}  			idx = AMDGPU_UCODE_ID_VCN + i;  			adev->firmware.ucode[idx].ucode_id = idx; -			adev->firmware.ucode[idx].fw = adev->vcn.fw; +			adev->firmware.ucode[idx].fw = adev->vcn.fw[i];  			adev->firmware.fw_size +=  				ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); -			if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(4, 0, 3)) +			if (amdgpu_ip_version(adev, UVD_HWIP, 0) == +			    IP_VERSION(4, 0, 3))  				break;  		}  		dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); @@ -1087,7 +1113,7 @@ static ssize_t amdgpu_debugfs_vcn_fwlog_read(struct file *f, char __user *buf,  	if (write_pos > read_pos) {  		available = write_pos - read_pos; -		read_num[0] = min(size, (size_t)available); +		read_num[0] = min_t(size_t, size, available);  	} else {  		read_num[0] = AMDGPU_VCNFW_LOG_SIZE - read_pos;  		available = read_num[0] + write_pos - plog->header_size; @@ -1179,7 +1205,7 @@ int amdgpu_vcn_process_poison_irq(struct amdgpu_device *adev,  		amdgpu_ras_interrupt_dispatch(adev, &ih_data);  	} else {  		if (adev->virt.ops && adev->virt.ops->ras_poison_handler) -			adev->virt.ops->ras_poison_handler(adev); +			adev->virt.ops->ras_poison_handler(adev, ras_if->block);  		else  			dev_warn(adev->dev,  				"No ras_poison_handler interface in SRIOV for VCN!\n"); @@ -1239,3 +1265,18 @@ int amdgpu_vcn_ras_sw_init(struct amdgpu_device *adev)  	return 0;  } + +int amdgpu_vcn_psp_update_sram(struct amdgpu_device *adev, int inst_idx, +			       enum AMDGPU_UCODE_ID ucode_id) +{ +	struct amdgpu_firmware_info ucode = { +		.ucode_id = (ucode_id ? ucode_id : +			    (inst_idx ? AMDGPU_UCODE_ID_VCN1_RAM : +					AMDGPU_UCODE_ID_VCN0_RAM)), +		.mc_addr = adev->vcn.inst[inst_idx].dpg_sram_gpu_addr, +		.ucode_size = ((uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_curr_addr - +			      (uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr), +	}; + +	return psp_execute_ip_fw_load(&adev->psp, &ucode); +}  |