]> git.dujemihanovic.xyz Git - linux.git/commitdiff
drm/amd/amdgpu: apply command submission parser for JPEG v1
authorDavid (Ming Qiang) Wu <David.Wu3@amd.com>
Thu, 5 Sep 2024 20:57:28 +0000 (16:57 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 10 Sep 2024 21:26:55 +0000 (17:26 -0400)
Similar to jpeg_v2_dec_ring_parse_cs() but it has different
register ranges and a few other registers access.

Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: David (Ming Qiang) Wu <David.Wu3@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 3d5adbdf1d01708777f2eda375227cbf7a98b9fe)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c
drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h

index 71f43a5c7f7217052e17b7322f9e2651baaefc0e..6e0e88076224bcf3ca3febf0dd36de51edac35fb 100644 (file)
@@ -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)
+{
+       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;
+}
index bbf33a6a397298be9c2bd40f2c61de4235f235f5..9654d22e03763c68590a8c9b576dc3cbb7e35038 100644 (file)
@@ -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__*/