diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c | 65 | 
1 files changed, 65 insertions, 0 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c index 22da65f45226..6b7d66b6d4cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c @@ -540,3 +540,68 @@ void amdgpu_jpeg_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_pri  			drm_printf(p, "\nInactive Instance:JPEG%d\n", i);  	}  } + +static inline bool amdgpu_jpeg_reg_valid(u32 reg) +{ +	if (reg < JPEG_REG_RANGE_START || reg > JPEG_REG_RANGE_END || +	    (reg >= JPEG_ATOMIC_RANGE_START && reg <= JPEG_ATOMIC_RANGE_END)) +		return false; +	else +		return true; +} + +/** + * amdgpu_jpeg_dec_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 + */ + +int amdgpu_jpeg_dec_parse_cs(struct amdgpu_cs_parser *parser, +			      struct amdgpu_job *job, +			      struct amdgpu_ib *ib) +{ +	u32 i, reg, res, cond, type; +	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) /* only support 0 at the moment */ +			return -EINVAL; + +		switch (type) { +		case PACKETJ_TYPE0: +			if (cond != PACKETJ_CONDITION_CHECK0 || +			    !amdgpu_jpeg_reg_valid(reg)) { +				dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); +				return -EINVAL; +			} +			break; +		case PACKETJ_TYPE3: +			if (cond != PACKETJ_CONDITION_CHECK3 || +			    !amdgpu_jpeg_reg_valid(reg)) { +				dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); +				return -EINVAL; +			} +			break; +		case PACKETJ_TYPE6: +			if (ib->ptr[i] == CP_PACKETJ_NOP) +				continue; +			dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); +			return -EINVAL; +		default: +			dev_err(adev->dev, "Unknown packet type %d !\n", type); +			return -EINVAL; +		} +	} + +	return 0; +} | 
