On Thu, Sep 5, 2024 at 5:40 PM David (Ming Qiang) Wu <David.Wu3@xxxxxxx> wrote: > > Similar to jpeg_v2_dec_ring_parse_cs() but it has different > register ranges and a few other registers access. > > Signed-off-by: David (Ming Qiang) Wu <David.Wu3@xxxxxxx> Series is: Acked-by: Alex Deucher <alexander.deucher@xxxxxxx> > --- > drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c | 76 +++++++++++++++++++++++++- > drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h | 11 ++++ > 2 files changed, 86 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c > index 71f43a5c7f72..e8c0bd228ec7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c > @@ -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,7 +304,10 @@ 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)); > - amdgpu_ring_write(ring, (vmid | (vmid << 4))); > + if (ring->funcs->parse_cs) > + amdgpu_ring_write(ring, 0); > + else > + amdgpu_ring_write(ring, (vmid | (vmid << 4))); > > amdgpu_ring_write(ring, > PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0)); > @@ -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 + > @@ -611,3 +619,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) > +{ > + uint32_t i, reg, res, cond, type; > + int32_t 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; > +} > diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h > index bbf33a6a3972..9654d22e0376 100644 > --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h > +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h > @@ -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__*/ > -- > 2.34.1 >