diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 191 | 
1 files changed, 109 insertions, 82 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 008a308a4eca..2658414c503d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -86,8 +86,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)  	for (i = 0; i < adev->vcn.num_vcn_inst; i++)  		atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0); -	switch (adev->asic_type) { -	case CHIP_RAVEN: +	switch (adev->ip_versions[UVD_HWIP][0]) { +	case IP_VERSION(1, 0, 0): +	case IP_VERSION(1, 0, 1):  		if (adev->apu_flags & AMD_APU_IS_RAVEN2)  			fw_name = FIRMWARE_RAVEN2;  		else if (adev->apu_flags & AMD_APU_IS_PICASSO) @@ -95,13 +96,13 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)  		else  			fw_name = FIRMWARE_RAVEN;  		break; -	case CHIP_ARCTURUS: +	case IP_VERSION(2, 5, 0):  		fw_name = FIRMWARE_ARCTURUS;  		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))  			adev->vcn.indirect_sram = true;  		break; -	case CHIP_RENOIR: +	case IP_VERSION(2, 2, 0):  		if (adev->apu_flags & AMD_APU_IS_RENOIR)  			fw_name = FIRMWARE_RENOIR;  		else @@ -111,58 +112,52 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))  			adev->vcn.indirect_sram = true;  		break; -	case CHIP_ALDEBARAN: +	case IP_VERSION(2, 6, 0):  		fw_name = FIRMWARE_ALDEBARAN;  		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))  			adev->vcn.indirect_sram = true;  		break; -	case CHIP_NAVI10: +	case IP_VERSION(2, 0, 0):  		fw_name = FIRMWARE_NAVI10;  		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))  			adev->vcn.indirect_sram = true;  		break; -	case CHIP_NAVI14: -		fw_name = FIRMWARE_NAVI14; -		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && -		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) -			adev->vcn.indirect_sram = true; -		break; -	case CHIP_NAVI12: -		fw_name = FIRMWARE_NAVI12; -		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && -		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) -			adev->vcn.indirect_sram = true; -		break; -	case CHIP_SIENNA_CICHLID: -		fw_name = FIRMWARE_SIENNA_CICHLID; +	case IP_VERSION(2, 0, 2): +		if (adev->asic_type == CHIP_NAVI12) +			fw_name = FIRMWARE_NAVI12; +		else +			fw_name = FIRMWARE_NAVI14;  		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))  			adev->vcn.indirect_sram = true;  		break; -	case CHIP_NAVY_FLOUNDER: -		fw_name = FIRMWARE_NAVY_FLOUNDER; +	case IP_VERSION(3, 0, 0): +		if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) +			fw_name = FIRMWARE_SIENNA_CICHLID; +		else +			fw_name = FIRMWARE_NAVY_FLOUNDER;  		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))  			adev->vcn.indirect_sram = true;  		break; -	case CHIP_VANGOGH: +	case IP_VERSION(3, 0, 2):  		fw_name = FIRMWARE_VANGOGH;  		break; -	case CHIP_DIMGREY_CAVEFISH: +	case IP_VERSION(3, 0, 16):  		fw_name = FIRMWARE_DIMGREY_CAVEFISH;  		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))  			adev->vcn.indirect_sram = true;  		break; -	case CHIP_BEIGE_GOBY: +	case IP_VERSION(3, 0, 33):  		fw_name = FIRMWARE_BEIGE_GOBY;  		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))  			adev->vcn.indirect_sram = true;  		break; -	case CHIP_YELLOW_CARP: +	case IP_VERSION(3, 1, 1):  		fw_name = FIRMWARE_YELLOW_CARP;  		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&  		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) @@ -330,7 +325,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)  		if (!adev->vcn.inst[i].saved_bo)  			return -ENOMEM; -		if (drm_dev_enter(&adev->ddev, &idx)) { +		if (drm_dev_enter(adev_to_drm(adev), &idx)) {  			memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);  			drm_dev_exit(idx);  		} @@ -354,7 +349,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)  		ptr = adev->vcn.inst[i].cpu_addr;  		if (adev->vcn.inst[i].saved_bo != NULL) { -			if (drm_dev_enter(&adev->ddev, &idx)) { +			if (drm_dev_enter(adev_to_drm(adev), &idx)) {  				memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);  				drm_dev_exit(idx);  			} @@ -367,7 +362,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)  			hdr = (const struct common_firmware_header *)adev->vcn.fw->data;  			if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {  				offset = le32_to_cpu(hdr->ucode_array_offset_bytes); -				if (drm_dev_enter(&adev->ddev, &idx)) { +				if (drm_dev_enter(adev_to_drm(adev), &idx)) {  					memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,  						    le32_to_cpu(hdr->ucode_size_bytes));  					drm_dev_exit(idx); @@ -541,15 +536,14 @@ int amdgpu_vcn_dec_sw_ring_test_ring(struct amdgpu_ring *ring)  }  static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, -				   struct amdgpu_bo *bo, +				   struct amdgpu_ib *ib_msg,  				   struct dma_fence **fence)  {  	struct amdgpu_device *adev = ring->adev;  	struct dma_fence *f = NULL;  	struct amdgpu_job *job;  	struct amdgpu_ib *ib; -	uint64_t addr; -	void *msg = NULL; +	uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);  	int i, r;  	r = amdgpu_job_alloc_with_ib(adev, 64, @@ -558,8 +552,6 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,  		goto err;  	ib = &job->ibs[0]; -	addr = amdgpu_bo_gpu_offset(bo); -	msg = amdgpu_bo_kptr(bo);  	ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);  	ib->ptr[1] = addr;  	ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0); @@ -576,9 +568,7 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,  	if (r)  		goto err_free; -	amdgpu_bo_fence(bo, f, false); -	amdgpu_bo_unreserve(bo); -	amdgpu_bo_free_kernel(&bo, NULL, (void **)&msg); +	amdgpu_ib_free(adev, ib_msg, f);  	if (fence)  		*fence = dma_fence_get(f); @@ -588,27 +578,26 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,  err_free:  	amdgpu_job_free(job); -  err: -	amdgpu_bo_unreserve(bo); -	amdgpu_bo_free_kernel(&bo, NULL, (void **)&msg); +	amdgpu_ib_free(adev, ib_msg, f);  	return r;  }  static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, -					 struct amdgpu_bo **bo) +		struct amdgpu_ib *ib)  {  	struct amdgpu_device *adev = ring->adev;  	uint32_t *msg;  	int r, i; -	*bo = NULL; -	r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, -				      AMDGPU_GEM_DOMAIN_VRAM, -				      bo, NULL, (void **)&msg); +	memset(ib, 0, sizeof(*ib)); +	r = amdgpu_ib_get(adev, NULL, AMDGPU_GPU_PAGE_SIZE * 2, +			AMDGPU_IB_POOL_DIRECT, +			ib);  	if (r)  		return r; +	msg = (uint32_t *)AMDGPU_GPU_PAGE_ALIGN((unsigned long)ib->ptr);  	msg[0] = cpu_to_le32(0x00000028);  	msg[1] = cpu_to_le32(0x00000038);  	msg[2] = cpu_to_le32(0x00000001); @@ -630,19 +619,20 @@ static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t hand  }  static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, -					  struct amdgpu_bo **bo) +					  struct amdgpu_ib *ib)  {  	struct amdgpu_device *adev = ring->adev;  	uint32_t *msg;  	int r, i; -	*bo = NULL; -	r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, -				      AMDGPU_GEM_DOMAIN_VRAM, -				      bo, NULL, (void **)&msg); +	memset(ib, 0, sizeof(*ib)); +	r = amdgpu_ib_get(adev, NULL, AMDGPU_GPU_PAGE_SIZE * 2, +			AMDGPU_IB_POOL_DIRECT, +			ib);  	if (r)  		return r; +	msg = (uint32_t *)AMDGPU_GPU_PAGE_ALIGN((unsigned long)ib->ptr);  	msg[0] = cpu_to_le32(0x00000028);  	msg[1] = cpu_to_le32(0x00000018);  	msg[2] = cpu_to_le32(0x00000000); @@ -658,21 +648,21 @@ static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han  int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)  {  	struct dma_fence *fence = NULL; -	struct amdgpu_bo *bo; +	struct amdgpu_ib ib;  	long r; -	r = amdgpu_vcn_dec_get_create_msg(ring, 1, &bo); +	r = amdgpu_vcn_dec_get_create_msg(ring, 1, &ib);  	if (r)  		goto error; -	r = amdgpu_vcn_dec_send_msg(ring, bo, NULL); +	r = amdgpu_vcn_dec_send_msg(ring, &ib, NULL);  	if (r)  		goto error; -	r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &bo); +	r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &ib);  	if (r)  		goto error; -	r = amdgpu_vcn_dec_send_msg(ring, bo, &fence); +	r = amdgpu_vcn_dec_send_msg(ring, &ib, &fence);  	if (r)  		goto error; @@ -688,8 +678,8 @@ error:  }  static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring, -				   struct amdgpu_bo *bo, -				   struct dma_fence **fence) +				      struct amdgpu_ib *ib_msg, +				      struct dma_fence **fence)  {  	struct amdgpu_vcn_decode_buffer *decode_buffer = NULL;  	const unsigned int ib_size_dw = 64; @@ -697,7 +687,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,  	struct dma_fence *f = NULL;  	struct amdgpu_job *job;  	struct amdgpu_ib *ib; -	uint64_t addr; +	uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);  	int i, r;  	r = amdgpu_job_alloc_with_ib(adev, ib_size_dw * 4, @@ -706,7 +696,6 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,  		goto err;  	ib = &job->ibs[0]; -	addr = amdgpu_bo_gpu_offset(bo);  	ib->length_dw = 0;  	ib->ptr[ib->length_dw++] = sizeof(struct amdgpu_vcn_decode_buffer) + 8; @@ -726,9 +715,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,  	if (r)  		goto err_free; -	amdgpu_bo_fence(bo, f, false); -	amdgpu_bo_unreserve(bo); -	amdgpu_bo_unref(&bo); +	amdgpu_ib_free(adev, ib_msg, f);  	if (fence)  		*fence = dma_fence_get(f); @@ -738,31 +725,29 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,  err_free:  	amdgpu_job_free(job); -  err: -	amdgpu_bo_unreserve(bo); -	amdgpu_bo_unref(&bo); +	amdgpu_ib_free(adev, ib_msg, f);  	return r;  }  int amdgpu_vcn_dec_sw_ring_test_ib(struct amdgpu_ring *ring, long timeout)  {  	struct dma_fence *fence = NULL; -	struct amdgpu_bo *bo; +	struct amdgpu_ib ib;  	long r; -	r = amdgpu_vcn_dec_get_create_msg(ring, 1, &bo); +	r = amdgpu_vcn_dec_get_create_msg(ring, 1, &ib);  	if (r)  		goto error; -	r = amdgpu_vcn_dec_sw_send_msg(ring, bo, NULL); +	r = amdgpu_vcn_dec_sw_send_msg(ring, &ib, NULL);  	if (r)  		goto error; -	r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &bo); +	r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &ib);  	if (r)  		goto error; -	r = amdgpu_vcn_dec_sw_send_msg(ring, bo, &fence); +	r = amdgpu_vcn_dec_sw_send_msg(ring, &ib, &fence);  	if (r)  		goto error; @@ -809,7 +794,7 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)  }  static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, -					 struct amdgpu_bo *bo, +					 struct amdgpu_ib *ib_msg,  					 struct dma_fence **fence)  {  	const unsigned ib_size_dw = 16; @@ -825,7 +810,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand  		return r;  	ib = &job->ibs[0]; -	addr = amdgpu_bo_gpu_offset(bo); +	addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);  	ib->length_dw = 0;  	ib->ptr[ib->length_dw++] = 0x00000018; @@ -863,7 +848,7 @@ err:  }  static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, -					  struct amdgpu_bo *bo, +					  struct amdgpu_ib *ib_msg,  					  struct dma_fence **fence)  {  	const unsigned ib_size_dw = 16; @@ -879,7 +864,7 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han  		return r;  	ib = &job->ibs[0]; -	addr = amdgpu_bo_gpu_offset(bo); +	addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);  	ib->length_dw = 0;  	ib->ptr[ib->length_dw++] = 0x00000018; @@ -918,21 +903,23 @@ err:  int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)  { +	struct amdgpu_device *adev = ring->adev;  	struct dma_fence *fence = NULL; -	struct amdgpu_bo *bo = NULL; +	struct amdgpu_ib ib;  	long r; -	r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, -				      AMDGPU_GEM_DOMAIN_VRAM, -				      &bo, NULL, NULL); +	memset(&ib, 0, sizeof(ib)); +	r = amdgpu_ib_get(adev, NULL, (128 << 10) + AMDGPU_GPU_PAGE_SIZE, +			AMDGPU_IB_POOL_DIRECT, +			&ib);  	if (r)  		return r; -	r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL); +	r = amdgpu_vcn_enc_get_create_msg(ring, 1, &ib, NULL);  	if (r)  		goto error; -	r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence); +	r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &ib, &fence);  	if (r)  		goto error; @@ -943,9 +930,49 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)  		r = 0;  error: +	amdgpu_ib_free(adev, &ib, fence);  	dma_fence_put(fence); -	amdgpu_bo_unreserve(bo); -	amdgpu_bo_free_kernel(&bo, NULL, NULL);  	return r;  } + +enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring) +{ +	switch(ring) { +	case 0: +		return AMDGPU_RING_PRIO_0; +	case 1: +		return AMDGPU_RING_PRIO_1; +	case 2: +		return AMDGPU_RING_PRIO_2; +	default: +		return AMDGPU_RING_PRIO_0; +	} +} + +void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev) +{ +	int i; +	unsigned int idx; + +	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; +			/* currently only support 2 FW instances */ +			if (i >= 2) { +				dev_info(adev->dev, "More then 2 VCN FW instances!\n"); +				break; +			} +			idx = AMDGPU_UCODE_ID_VCN + i; +			adev->firmware.ucode[idx].ucode_id = idx; +			adev->firmware.ucode[idx].fw = adev->vcn.fw; +			adev->firmware.fw_size += +				ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); +		} +		dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); +	} +}  |