Commit 1a8d947c authored by David (Ming Qiang) Wu's avatar David (Ming Qiang) Wu Committed by Wen Zhiwei
Browse files

drm/amd/amdgpu: apply command submission parser for JPEG v1

stable inclusion
from stable-v6.6.52
commit ff65ae25d3cbcd8737e5971230031f0826a33250
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAYXOD

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=ff65ae25d3cbcd8737e5971230031f0826a33250



--------------------------------

commit 8409fb50ce48d66cf9dc5391f03f05c56c430605 upstream.

Similar to jpeg_v2_dec_ring_parse_cs() but it has different
register ranges and a few other registers access.

Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarDavid (Ming Qiang) Wu <David.Wu3@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 3d5adbdf1d01708777f2eda375227cbf7a98b9fe)
Cc: stable@vger.kernel.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarWen Zhiwei <wenzhiwei@kylinos.cn>
parent bda19b9b
Loading
Loading
Loading
Loading
+75 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@

#include "amdgpu.h"
#include "amdgpu_jpeg.h"
#include "amdgpu_cs.h"
#include "soc15.h"
#include "soc15d.h"
#include "vcn_v1_0.h"
@@ -34,6 +35,9 @@
static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev);
static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring);
static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser,
				     struct amdgpu_job *job,
				     struct amdgpu_ib *ib);

static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val)
{
@@ -300,6 +304,9 @@ static void jpeg_v1_0_decode_ring_emit_ib(struct amdgpu_ring *ring,

	amdgpu_ring_write(ring,
		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0));
	if (ring->funcs->parse_cs)
		amdgpu_ring_write(ring, 0);
	else
		amdgpu_ring_write(ring, (vmid | (vmid << 4)));

	amdgpu_ring_write(ring,
@@ -554,6 +561,7 @@ static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = {
	.get_rptr = jpeg_v1_0_decode_ring_get_rptr,
	.get_wptr = jpeg_v1_0_decode_ring_get_wptr,
	.set_wptr = jpeg_v1_0_decode_ring_set_wptr,
	.parse_cs = jpeg_v1_dec_ring_parse_cs,
	.emit_frame_size =
		6 + 6 + /* hdp invalidate / flush */
		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
@@ -612,3 +620,69 @@ static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring)

	vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
}

/**
 * jpeg_v1_dec_ring_parse_cs - command submission parser
 *
 * @parser: Command submission parser context
 * @job: the job to parse
 * @ib: the IB to parse
 *
 * Parse the command stream, return -EINVAL for invalid packet,
 * 0 otherwise
 */
static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser,
				     struct amdgpu_job *job,
				     struct amdgpu_ib *ib)
{
	u32 i, reg, res, cond, type;
	int ret = 0;
	struct amdgpu_device *adev = parser->adev;

	for (i = 0; i < ib->length_dw ; i += 2) {
		reg  = CP_PACKETJ_GET_REG(ib->ptr[i]);
		res  = CP_PACKETJ_GET_RES(ib->ptr[i]);
		cond = CP_PACKETJ_GET_COND(ib->ptr[i]);
		type = CP_PACKETJ_GET_TYPE(ib->ptr[i]);

		if (res || cond != PACKETJ_CONDITION_CHECK0) /* only allow 0 for now */
			return -EINVAL;

		if (reg >= JPEG_V1_REG_RANGE_START && reg <= JPEG_V1_REG_RANGE_END)
			continue;

		switch (type) {
		case PACKETJ_TYPE0:
			if (reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_HIGH &&
			    reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_LOW &&
			    reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_HIGH &&
			    reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_LOW &&
			    reg != JPEG_V1_REG_CTX_INDEX &&
			    reg != JPEG_V1_REG_CTX_DATA) {
				ret = -EINVAL;
			}
			break;
		case PACKETJ_TYPE1:
			if (reg != JPEG_V1_REG_CTX_DATA)
				ret = -EINVAL;
			break;
		case PACKETJ_TYPE3:
			if (reg != JPEG_V1_REG_SOFT_RESET)
				ret = -EINVAL;
			break;
		case PACKETJ_TYPE6:
			if (ib->ptr[i] != CP_PACKETJ_NOP)
				ret = -EINVAL;
			break;
		default:
			ret = -EINVAL;
		}

		if (ret) {
			dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]);
			break;
		}
	}

	return ret;
}
+11 −0
Original line number Diff line number Diff line
@@ -29,4 +29,15 @@ int jpeg_v1_0_sw_init(void *handle);
void jpeg_v1_0_sw_fini(void *handle);
void jpeg_v1_0_start(struct amdgpu_device *adev, int mode);

#define JPEG_V1_REG_RANGE_START	0x8000
#define JPEG_V1_REG_RANGE_END	0x803f

#define JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_HIGH	0x8238
#define JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_LOW	0x8239
#define JPEG_V1_LMI_JPEG_READ_64BIT_BAR_HIGH	0x825a
#define JPEG_V1_LMI_JPEG_READ_64BIT_BAR_LOW	0x825b
#define JPEG_V1_REG_CTX_INDEX			0x8328
#define JPEG_V1_REG_CTX_DATA			0x8329
#define JPEG_V1_REG_SOFT_RESET			0x83a0

#endif /*__JPEG_V1_0_H__*/