diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 110 | 
1 files changed, 86 insertions, 24 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index b81b77a9efa6..ac6fe0ae4609 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -101,39 +101,101 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)  	}  } +static int amdgpu_atomfirmware_allocate_fb_v2_1(struct amdgpu_device *adev, +	struct vram_usagebyfirmware_v2_1 *fw_usage, int *usage_bytes) +{ +	u32 start_addr, fw_size, drv_size; + +	start_addr = le32_to_cpu(fw_usage->start_address_in_kb); +	fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb); +	drv_size = le16_to_cpu(fw_usage->used_by_driver_in_kb); + +	DRM_DEBUG("atom firmware v2_1 requested %08x %dkb fw %dkb drv\n", +			  start_addr, +			  fw_size, +			  drv_size); + +	if ((start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == +		(u32)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << +		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { +		/* Firmware request VRAM reservation for SR-IOV */ +		adev->mman.fw_vram_usage_start_offset = (start_addr & +			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; +		adev->mman.fw_vram_usage_size = fw_size << 10; +		/* Use the default scratch size */ +		*usage_bytes = 0; +	} else { +		*usage_bytes = drv_size << 10; +	} +	return 0; +} + +static int amdgpu_atomfirmware_allocate_fb_v2_2(struct amdgpu_device *adev, +		struct vram_usagebyfirmware_v2_2 *fw_usage, int *usage_bytes) +{ +	u32 fw_start_addr, fw_size, drv_start_addr, drv_size; + +	fw_start_addr = le32_to_cpu(fw_usage->fw_region_start_address_in_kb); +	fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb); + +	drv_start_addr = le32_to_cpu(fw_usage->driver_region0_start_address_in_kb); +	drv_size = le32_to_cpu(fw_usage->used_by_driver_region0_in_kb); + +	DRM_DEBUG("atom requested fw start at %08x %dkb and drv start at %08x %dkb\n", +			  fw_start_addr, +			  fw_size, +			  drv_start_addr, +			  drv_size); + +	if (amdgpu_sriov_vf(adev) && +	    ((fw_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION << +		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) == 0)) { +		/* Firmware request VRAM reservation for SR-IOV */ +		adev->mman.fw_vram_usage_start_offset = (fw_start_addr & +			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; +		adev->mman.fw_vram_usage_size = fw_size << 10; +	} + +	if (amdgpu_sriov_vf(adev) && +	    ((drv_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION << +		ATOM_VRAM_OPERATION_FLAGS_SHIFT)) == 0)) { +		/* driver request VRAM reservation for SR-IOV */ +		adev->mman.drv_vram_usage_start_offset = (drv_start_addr & +			(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; +		adev->mman.drv_vram_usage_size = drv_size << 10; +	} + +	*usage_bytes = 0; +	return 0; +} +  int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)  {  	struct atom_context *ctx = adev->mode_info.atom_context;  	int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,  						vram_usagebyfirmware); -	struct vram_usagebyfirmware_v2_1 *firmware_usage; -	uint32_t start_addr, size; -	uint16_t data_offset; +	struct vram_usagebyfirmware_v2_1 *fw_usage_v2_1; +	struct vram_usagebyfirmware_v2_2 *fw_usage_v2_2; +	u16 data_offset; +	u8 frev, crev;  	int usage_bytes = 0; -	if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { -		firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); -		DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n", -			  le32_to_cpu(firmware_usage->start_address_in_kb), -			  le16_to_cpu(firmware_usage->used_by_firmware_in_kb), -			  le16_to_cpu(firmware_usage->used_by_driver_in_kb)); - -		start_addr = le32_to_cpu(firmware_usage->start_address_in_kb); -		size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb); - -		if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == -			(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << -			ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { -			/* Firmware request VRAM reservation for SR-IOV */ -			adev->mman.fw_vram_usage_start_offset = (start_addr & -				(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; -			adev->mman.fw_vram_usage_size = size << 10; -			/* Use the default scratch size */ -			usage_bytes = 0; -		} else { -			usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10; +	if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) { +		if (frev == 2 && crev == 1) { +			fw_usage_v2_1 = +				(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); +			amdgpu_atomfirmware_allocate_fb_v2_1(adev, +					fw_usage_v2_1, +					&usage_bytes); +		} else if (frev >= 2 && crev >= 2) { +			fw_usage_v2_2 = +				(struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset); +			amdgpu_atomfirmware_allocate_fb_v2_2(adev, +					fw_usage_v2_2, +					&usage_bytes);  		}  	} +  	ctx->scratch_size_bytes = 0;  	if (usage_bytes == 0)  		usage_bytes = 20 * 1024; | 
