|
23 | 23 |
|
24 | 24 | #include "amdgpu.h" |
25 | 25 | #include "amdgpu_jpeg.h" |
| 26 | +#include "amdgpu_cs.h" |
26 | 27 | #include "soc15.h" |
27 | 28 | #include "soc15d.h" |
28 | 29 | #include "vcn_v1_0.h" |
|
34 | 35 | static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); |
35 | 36 | static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev); |
36 | 37 | static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring); |
| 38 | +static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser, |
| 39 | + struct amdgpu_job *job, |
| 40 | + struct amdgpu_ib *ib); |
37 | 41 |
|
38 | 42 | static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val) |
39 | 43 | { |
@@ -300,7 +304,10 @@ static void jpeg_v1_0_decode_ring_emit_ib(struct amdgpu_ring *ring, |
300 | 304 |
|
301 | 305 | amdgpu_ring_write(ring, |
302 | 306 | PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); |
303 | | - amdgpu_ring_write(ring, (vmid | (vmid << 4))); |
| 307 | + if (ring->funcs->parse_cs) |
| 308 | + amdgpu_ring_write(ring, 0); |
| 309 | + else |
| 310 | + amdgpu_ring_write(ring, (vmid | (vmid << 4))); |
304 | 311 |
|
305 | 312 | amdgpu_ring_write(ring, |
306 | 313 | 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 = { |
554 | 561 | .get_rptr = jpeg_v1_0_decode_ring_get_rptr, |
555 | 562 | .get_wptr = jpeg_v1_0_decode_ring_get_wptr, |
556 | 563 | .set_wptr = jpeg_v1_0_decode_ring_set_wptr, |
| 564 | + .parse_cs = jpeg_v1_dec_ring_parse_cs, |
557 | 565 | .emit_frame_size = |
558 | 566 | 6 + 6 + /* hdp invalidate / flush */ |
559 | 567 | SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + |
@@ -612,3 +620,69 @@ static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring) |
612 | 620 |
|
613 | 621 | vcn_v1_0_set_pg_for_begin_use(ring, set_clocks); |
614 | 622 | } |
| 623 | + |
| 624 | +/** |
| 625 | + * jpeg_v1_dec_ring_parse_cs - command submission parser |
| 626 | + * |
| 627 | + * @parser: Command submission parser context |
| 628 | + * @job: the job to parse |
| 629 | + * @ib: the IB to parse |
| 630 | + * |
| 631 | + * Parse the command stream, return -EINVAL for invalid packet, |
| 632 | + * 0 otherwise |
| 633 | + */ |
| 634 | +static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser, |
| 635 | + struct amdgpu_job *job, |
| 636 | + struct amdgpu_ib *ib) |
| 637 | +{ |
| 638 | + u32 i, reg, res, cond, type; |
| 639 | + int ret = 0; |
| 640 | + struct amdgpu_device *adev = parser->adev; |
| 641 | + |
| 642 | + for (i = 0; i < ib->length_dw ; i += 2) { |
| 643 | + reg = CP_PACKETJ_GET_REG(ib->ptr[i]); |
| 644 | + res = CP_PACKETJ_GET_RES(ib->ptr[i]); |
| 645 | + cond = CP_PACKETJ_GET_COND(ib->ptr[i]); |
| 646 | + type = CP_PACKETJ_GET_TYPE(ib->ptr[i]); |
| 647 | + |
| 648 | + if (res || cond != PACKETJ_CONDITION_CHECK0) /* only allow 0 for now */ |
| 649 | + return -EINVAL; |
| 650 | + |
| 651 | + if (reg >= JPEG_V1_REG_RANGE_START && reg <= JPEG_V1_REG_RANGE_END) |
| 652 | + continue; |
| 653 | + |
| 654 | + switch (type) { |
| 655 | + case PACKETJ_TYPE0: |
| 656 | + if (reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_HIGH && |
| 657 | + reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_LOW && |
| 658 | + reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_HIGH && |
| 659 | + reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_LOW && |
| 660 | + reg != JPEG_V1_REG_CTX_INDEX && |
| 661 | + reg != JPEG_V1_REG_CTX_DATA) { |
| 662 | + ret = -EINVAL; |
| 663 | + } |
| 664 | + break; |
| 665 | + case PACKETJ_TYPE1: |
| 666 | + if (reg != JPEG_V1_REG_CTX_DATA) |
| 667 | + ret = -EINVAL; |
| 668 | + break; |
| 669 | + case PACKETJ_TYPE3: |
| 670 | + if (reg != JPEG_V1_REG_SOFT_RESET) |
| 671 | + ret = -EINVAL; |
| 672 | + break; |
| 673 | + case PACKETJ_TYPE6: |
| 674 | + if (ib->ptr[i] != CP_PACKETJ_NOP) |
| 675 | + ret = -EINVAL; |
| 676 | + break; |
| 677 | + default: |
| 678 | + ret = -EINVAL; |
| 679 | + } |
| 680 | + |
| 681 | + if (ret) { |
| 682 | + dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); |
| 683 | + break; |
| 684 | + } |
| 685 | + } |
| 686 | + |
| 687 | + return ret; |
| 688 | +} |
0 commit comments