diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 188 | 
1 files changed, 33 insertions, 155 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 9d870444d7d6..f96464e2c157 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -28,19 +28,10 @@  #include <linux/module.h>  #include <linux/pci.h> -#include <drm/drm.h> -  #include "amdgpu.h"  #include "amdgpu_pm.h"  #include "amdgpu_vcn.h"  #include "soc15d.h" -#include "soc15_common.h" - -#include "vcn/vcn_1_0_offset.h" -#include "vcn/vcn_1_0_sh_mask.h" - -/* 1 second timeout */ -#define VCN_IDLE_TIMEOUT	msecs_to_jiffies(1000)  /* Firmware Names */  #define FIRMWARE_RAVEN		"amdgpu/raven_vcn.bin" @@ -84,6 +75,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)  		break;  	case CHIP_ARCTURUS:  		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:  		fw_name = FIRMWARE_RENOIR; @@ -174,15 +168,15 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)  			dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);  			return r;  		} -	} -	if (adev->vcn.indirect_sram) { -		r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE, -			    AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.dpg_sram_bo, -			    &adev->vcn.dpg_sram_gpu_addr, &adev->vcn.dpg_sram_cpu_addr); -		if (r) { -			dev_err(adev->dev, "(%d) failed to allocate DPG bo\n", r); -			return r; +		if (adev->vcn.indirect_sram) { +			r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE, +					AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo, +					&adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr); +			if (r) { +				dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r); +				return r; +			}  		}  	} @@ -195,15 +189,14 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)  	cancel_delayed_work_sync(&adev->vcn.idle_work); -	if (adev->vcn.indirect_sram) { -		amdgpu_bo_free_kernel(&adev->vcn.dpg_sram_bo, -				      &adev->vcn.dpg_sram_gpu_addr, -				      (void **)&adev->vcn.dpg_sram_cpu_addr); -	} -  	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {  		if (adev->vcn.harvest_config & (1 << j))  			continue; +		if (adev->vcn.indirect_sram) { +			amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo, +						  &adev->vcn.inst[j].dpg_sram_gpu_addr, +						  (void **)&adev->vcn.inst[j].dpg_sram_cpu_addr); +		}  		kvfree(adev->vcn.inst[j].saved_bo);  		amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo, @@ -214,8 +207,6 @@ 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_ring_fini(&adev->vcn.inst[j].ring_jpeg);  	}  	release_firmware(adev->vcn.fw); @@ -296,6 +287,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)  	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {  		if (adev->vcn.harvest_config & (1 << j))  			continue; +  		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {  			fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);  		} @@ -308,26 +300,17 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)  			else  				new_state.fw_based = VCN_DPG_STATE__UNPAUSE; -			if (amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_jpeg)) -				new_state.jpeg = VCN_DPG_STATE__PAUSE; -			else -				new_state.jpeg = VCN_DPG_STATE__UNPAUSE; - -			adev->vcn.pause_dpg_mode(adev, &new_state); +			adev->vcn.pause_dpg_mode(adev, j, &new_state);  		} -		fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_jpeg);  		fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec);  		fences += fence[j];  	}  	if (fences == 0) {  		amdgpu_gfx_off_ctrl(adev, true); -		if (adev->asic_type < CHIP_ARCTURUS && adev->pm.dpm_enabled) -			amdgpu_dpm_enable_uvd(adev, false); -		else -			amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, -							       AMD_PG_STATE_GATE); +		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, +		       AMD_PG_STATE_GATE);  	} else {  		schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);  	} @@ -340,11 +323,8 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)  	if (set_clocks) {  		amdgpu_gfx_off_ctrl(adev, false); -		if (adev->asic_type < CHIP_ARCTURUS && adev->pm.dpm_enabled) -			amdgpu_dpm_enable_uvd(adev, true); -		else -			amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, -							       AMD_PG_STATE_UNGATE); +		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, +		       AMD_PG_STATE_UNGATE);  	}  	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{ @@ -360,17 +340,10 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)  		else  			new_state.fw_based = VCN_DPG_STATE__UNPAUSE; -		if (amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_jpeg)) -			new_state.jpeg = VCN_DPG_STATE__PAUSE; -		else -			new_state.jpeg = VCN_DPG_STATE__UNPAUSE; -  		if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)  			new_state.fw_based = VCN_DPG_STATE__PAUSE; -		else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) -			new_state.jpeg = VCN_DPG_STATE__PAUSE; -		adev->vcn.pause_dpg_mode(adev, &new_state); +		adev->vcn.pause_dpg_mode(adev, ring->me, &new_state);  	}  } @@ -520,9 +493,14 @@ 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 amdgpu_device *adev = ring->adev;  	struct dma_fence *fence;  	long r; +	/* temporarily disable ib test for sriov */ +	if (amdgpu_sriov_vf(adev)) +		return 0; +  	r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL);  	if (r)  		goto error; @@ -678,10 +656,15 @@ 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;  	long r; +	/* temporarily disable ib test for sriov */ +	if (amdgpu_sriov_vf(adev)) +		return 0; +  	r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,  				      AMDGPU_GEM_DOMAIN_VRAM,  				      &bo, NULL, NULL); @@ -708,108 +691,3 @@ error:  	amdgpu_bo_unref(&bo);  	return r;  } - -int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) -{ -	struct amdgpu_device *adev = ring->adev; -	uint32_t tmp = 0; -	unsigned i; -	int r; - -	WREG32(adev->vcn.inst[ring->me].external.jpeg_pitch, 0xCAFEDEAD); -	r = amdgpu_ring_alloc(ring, 3); -	if (r) -		return r; - -	amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.jpeg_pitch, 0)); -	amdgpu_ring_write(ring, 0xDEADBEEF); -	amdgpu_ring_commit(ring); - -	for (i = 0; i < adev->usec_timeout; i++) { -		tmp = RREG32(adev->vcn.inst[ring->me].external.jpeg_pitch); -		if (tmp == 0xDEADBEEF) -			break; -		udelay(1); -	} - -	if (i >= adev->usec_timeout) -		r = -ETIMEDOUT; - -	return r; -} - -static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle, -		struct dma_fence **fence) -{ -	struct amdgpu_device *adev = ring->adev; -	struct amdgpu_job *job; -	struct amdgpu_ib *ib; -	struct dma_fence *f = NULL; -	const unsigned ib_size_dw = 16; -	int i, r; - -	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); -	if (r) -		return r; - -	ib = &job->ibs[0]; - -	ib->ptr[0] = PACKETJ(adev->vcn.internal.jpeg_pitch, 0, 0, PACKETJ_TYPE0); -	ib->ptr[1] = 0xDEADBEEF; -	for (i = 2; i < 16; i += 2) { -		ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); -		ib->ptr[i+1] = 0; -	} -	ib->length_dw = 16; - -	r = amdgpu_job_submit_direct(job, ring, &f); -	if (r) -		goto err; - -	if (fence) -		*fence = dma_fence_get(f); -	dma_fence_put(f); - -	return 0; - -err: -	amdgpu_job_free(job); -	return r; -} - -int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout) -{ -	struct amdgpu_device *adev = ring->adev; -	uint32_t tmp = 0; -	unsigned i; -	struct dma_fence *fence = NULL; -	long r = 0; - -	r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence); -	if (r) -		goto error; - -	r = dma_fence_wait_timeout(fence, false, timeout); -	if (r == 0) { -		r = -ETIMEDOUT; -		goto error; -	} else if (r < 0) { -		goto error; -	} else { -		r = 0; -	} - -	for (i = 0; i < adev->usec_timeout; i++) { -		tmp = RREG32(adev->vcn.inst[ring->me].external.jpeg_pitch); -		if (tmp == 0xDEADBEEF) -			break; -		udelay(1); -	} - -	if (i >= adev->usec_timeout) -		r = -ETIMEDOUT; - -	dma_fence_put(fence); -error: -	return r; -} |