#include "amdgpu.h"
 #include "amdgpu_jpeg.h"
+#include "amdgpu_cs.h"
 #include "soc15.h"
 #include "soc15d.h"
 #include "vcn_v1_0.h"
 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)
 {
 
        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));
        .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 +
 
        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;
+}
 
 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__*/