|
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 +
|
@@ -611,3 +619,69 @@ static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring)
|
611 | 619 |
|
612 | 620 | vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
|
613 | 621 | }
|
| 622 | + |
| 623 | +/** |
| 624 | + * jpeg_v1_dec_ring_parse_cs - command submission parser |
| 625 | + * |
| 626 | + * @parser: Command submission parser context |
| 627 | + * @job: the job to parse |
| 628 | + * @ib: the IB to parse |
| 629 | + * |
| 630 | + * Parse the command stream, return -EINVAL for invalid packet, |
| 631 | + * 0 otherwise |
| 632 | + */ |
| 633 | +static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser, |
| 634 | + struct amdgpu_job *job, |
| 635 | + struct amdgpu_ib *ib) |
| 636 | +{ |
| 637 | + u32 i, reg, res, cond, type; |
| 638 | + int ret = 0; |
| 639 | + struct amdgpu_device *adev = parser->adev; |
| 640 | + |
| 641 | + for (i = 0; i < ib->length_dw ; i += 2) { |
| 642 | + reg = CP_PACKETJ_GET_REG(ib->ptr[i]); |
| 643 | + res = CP_PACKETJ_GET_RES(ib->ptr[i]); |
| 644 | + cond = CP_PACKETJ_GET_COND(ib->ptr[i]); |
| 645 | + type = CP_PACKETJ_GET_TYPE(ib->ptr[i]); |
| 646 | + |
| 647 | + if (res || cond != PACKETJ_CONDITION_CHECK0) /* only allow 0 for now */ |
| 648 | + return -EINVAL; |
| 649 | + |
| 650 | + if (reg >= JPEG_V1_REG_RANGE_START && reg <= JPEG_V1_REG_RANGE_END) |
| 651 | + continue; |
| 652 | + |
| 653 | + switch (type) { |
| 654 | + case PACKETJ_TYPE0: |
| 655 | + if (reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_HIGH && |
| 656 | + reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_LOW && |
| 657 | + reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_HIGH && |
| 658 | + reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_LOW && |
| 659 | + reg != JPEG_V1_REG_CTX_INDEX && |
| 660 | + reg != JPEG_V1_REG_CTX_DATA) { |
| 661 | + ret = -EINVAL; |
| 662 | + } |
| 663 | + break; |
| 664 | + case PACKETJ_TYPE1: |
| 665 | + if (reg != JPEG_V1_REG_CTX_DATA) |
| 666 | + ret = -EINVAL; |
| 667 | + break; |
| 668 | + case PACKETJ_TYPE3: |
| 669 | + if (reg != JPEG_V1_REG_SOFT_RESET) |
| 670 | + ret = -EINVAL; |
| 671 | + break; |
| 672 | + case PACKETJ_TYPE6: |
| 673 | + if (ib->ptr[i] != CP_PACKETJ_NOP) |
| 674 | + ret = -EINVAL; |
| 675 | + break; |
| 676 | + default: |
| 677 | + ret = -EINVAL; |
| 678 | + } |
| 679 | + |
| 680 | + if (ret) { |
| 681 | + dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); |
| 682 | + break; |
| 683 | + } |
| 684 | + } |
| 685 | + |
| 686 | + return ret; |
| 687 | +} |
0 commit comments