Commit bc224553 authored by James Zhu's avatar James Zhu Committed by Alex Deucher
Browse files

drm/amdgpu/jpeg: add multiple jpeg rings support



Add multiple jpeg rings support.

Signed-off-by: default avatarJames Zhu <James.Zhu@amd.com>
Reviewed-by: default avatarLeo Liu <leo.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 31c0ec84
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -45,13 +45,14 @@ int amdgpu_jpeg_sw_init(struct amdgpu_device *adev)

int amdgpu_jpeg_sw_fini(struct amdgpu_device *adev)
{
	int i;
	int i, j;

	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
		if (adev->jpeg.harvest_config & (1 << i))
			continue;

		amdgpu_ring_fini(&adev->jpeg.inst[i].ring_dec);
		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j)
			amdgpu_ring_fini(&adev->jpeg.inst[i].ring_dec[j]);
	}

	mutex_destroy(&adev->jpeg.jpeg_pg_lock);
@@ -76,13 +77,14 @@ static void amdgpu_jpeg_idle_work_handler(struct work_struct *work)
	struct amdgpu_device *adev =
		container_of(work, struct amdgpu_device, jpeg.idle_work.work);
	unsigned int fences = 0;
	unsigned int i;
	unsigned int i, j;

	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
		if (adev->jpeg.harvest_config & (1 << i))
			continue;

		fences += amdgpu_fence_count_emitted(&adev->jpeg.inst[i].ring_dec);
		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j)
			fences += amdgpu_fence_count_emitted(&adev->jpeg.inst[i].ring_dec[j]);
	}

	if (!fences && !atomic_read(&adev->jpeg.total_submission_cnt))
@@ -122,17 +124,17 @@ int amdgpu_jpeg_dec_ring_test_ring(struct amdgpu_ring *ring)
	if (amdgpu_sriov_vf(adev))
		return 0;

	WREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch, 0xCAFEDEAD);
	WREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch[ring->pipe], 0xCAFEDEAD);
	r = amdgpu_ring_alloc(ring, 3);
	if (r)
		return r;

	amdgpu_ring_write(ring, PACKET0(adev->jpeg.internal.jpeg_pitch, 0));
	amdgpu_ring_write(ring, PACKET0(adev->jpeg.internal.jpeg_pitch[ring->pipe], 0));
	amdgpu_ring_write(ring, 0xDEADBEEF);
	amdgpu_ring_commit(ring);

	for (i = 0; i < adev->usec_timeout; i++) {
		tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch);
		tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch[ring->pipe]);
		if (tmp == 0xDEADBEEF)
			break;
		udelay(1);
@@ -161,8 +163,7 @@ static int amdgpu_jpeg_dec_set_reg(struct amdgpu_ring *ring, uint32_t handle,

	ib = &job->ibs[0];

	ib->ptr[0] = PACKETJ(adev->jpeg.internal.jpeg_pitch, 0, 0,
			     PACKETJ_TYPE0);
	ib->ptr[0] = PACKETJ(adev->jpeg.internal.jpeg_pitch[ring->pipe], 0, 0, PACKETJ_TYPE0);
	ib->ptr[1] = 0xDEADBEEF;
	for (i = 2; i < 16; i += 2) {
		ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
@@ -208,7 +209,7 @@ int amdgpu_jpeg_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
	}
	if (!amdgpu_sriov_vf(adev)) {
		for (i = 0; i < adev->usec_timeout; i++) {
			tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch);
			tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch[ring->pipe]);
			if (tmp == 0xDEADBEEF)
				break;
			udelay(1);
+4 −2
Original line number Diff line number Diff line
@@ -27,16 +27,17 @@
#include "amdgpu_ras.h"

#define AMDGPU_MAX_JPEG_INSTANCES	2
#define AMDGPU_MAX_JPEG_RINGS		8

#define AMDGPU_JPEG_HARVEST_JPEG0 (1 << 0)
#define AMDGPU_JPEG_HARVEST_JPEG1 (1 << 1)

struct amdgpu_jpeg_reg{
	unsigned jpeg_pitch;
	unsigned jpeg_pitch[AMDGPU_MAX_JPEG_RINGS];
};

struct amdgpu_jpeg_inst {
	struct amdgpu_ring ring_dec;
	struct amdgpu_ring ring_dec[AMDGPU_MAX_JPEG_RINGS];
	struct amdgpu_irq_src irq;
	struct amdgpu_jpeg_reg external;
};
@@ -48,6 +49,7 @@ struct amdgpu_jpeg_ras {
struct amdgpu_jpeg {
	uint8_t	num_jpeg_inst;
	struct amdgpu_jpeg_inst inst[AMDGPU_MAX_JPEG_INSTANCES];
	unsigned num_jpeg_rings;
	struct amdgpu_jpeg_reg internal;
	unsigned harvest_config;
	struct delayed_work idle_work;
+3 −2
Original line number Diff line number Diff line
@@ -462,7 +462,8 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
			if (adev->jpeg.harvest_config & (1 << i))
				continue;

			if (adev->jpeg.inst[i].ring_dec.sched.ready)
			for (j = 0; j < adev->jpeg.num_jpeg_rings; j++)
				if (adev->jpeg.inst[i].ring_dec[j].sched.ready)
					++num_rings;
		}
		ib_start_alignment = 16;
+6 −6
Original line number Diff line number Diff line
@@ -437,7 +437,7 @@ static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev,

	switch (entry->src_id) {
	case 126:
		amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
		amdgpu_fence_process(adev->jpeg.inst->ring_dec);
		break;
	default:
		DRM_ERROR("Unhandled interrupt: %d %d\n",
@@ -484,7 +484,7 @@ int jpeg_v1_0_sw_init(void *handle)
	if (r)
		return r;

	ring = &adev->jpeg.inst->ring_dec;
	ring = adev->jpeg.inst->ring_dec;
	ring->vm_hub = AMDGPU_MMHUB0(0);
	sprintf(ring->name, "jpeg_dec");
	r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
@@ -492,7 +492,7 @@ int jpeg_v1_0_sw_init(void *handle)
	if (r)
		return r;

	adev->jpeg.internal.jpeg_pitch = adev->jpeg.inst->external.jpeg_pitch =
	adev->jpeg.internal.jpeg_pitch[0] = adev->jpeg.inst->external.jpeg_pitch[0] =
		SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);

	return 0;
@@ -509,7 +509,7 @@ void jpeg_v1_0_sw_fini(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	amdgpu_ring_fini(&adev->jpeg.inst[0].ring_dec);
	amdgpu_ring_fini(adev->jpeg.inst->ring_dec);
}

/**
@@ -522,7 +522,7 @@ void jpeg_v1_0_sw_fini(void *handle)
 */
void jpeg_v1_0_start(struct amdgpu_device *adev, int mode)
{
	struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
	struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;

	if (mode == 0) {
		WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
@@ -579,7 +579,7 @@ static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = {

static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev)
{
	adev->jpeg.inst->ring_dec.funcs = &jpeg_v1_0_decode_ring_vm_funcs;
	adev->jpeg.inst->ring_dec->funcs = &jpeg_v1_0_decode_ring_vm_funcs;
	DRM_INFO("JPEG decode is enabled in VM mode\n");
}

+7 −7
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ static int jpeg_v2_0_sw_init(void *handle)
	if (r)
		return r;

	ring = &adev->jpeg.inst->ring_dec;
	ring = adev->jpeg.inst->ring_dec;
	ring->use_doorbell = true;
	ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
	ring->vm_hub = AMDGPU_MMHUB0(0);
@@ -93,8 +93,8 @@ static int jpeg_v2_0_sw_init(void *handle)
	if (r)
		return r;

	adev->jpeg.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
	adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
	adev->jpeg.internal.jpeg_pitch[0] = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
	adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);

	return 0;
}
@@ -129,7 +129,7 @@ static int jpeg_v2_0_sw_fini(void *handle)
static int jpeg_v2_0_hw_init(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
	struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
	int r;

	adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
@@ -312,7 +312,7 @@ static void jpeg_v2_0_enable_clock_gating(struct amdgpu_device *adev)
 */
static int jpeg_v2_0_start(struct amdgpu_device *adev)
{
	struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
	struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
	int r;

	if (adev->pm.dpm_enabled)
@@ -729,7 +729,7 @@ static int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev,

	switch (entry->src_id) {
	case VCN_2_0__SRCID__JPEG_DECODE:
		amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
		amdgpu_fence_process(adev->jpeg.inst->ring_dec);
		break;
	default:
		DRM_ERROR("Unhandled interrupt: %d %d\n",
@@ -791,7 +791,7 @@ static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = {

static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev)
{
	adev->jpeg.inst->ring_dec.funcs = &jpeg_v2_0_dec_ring_vm_funcs;
	adev->jpeg.inst->ring_dec->funcs = &jpeg_v2_0_dec_ring_vm_funcs;
	DRM_INFO("JPEG decode is enabled in VM mode\n");
}

Loading