diff options
author | Leo Liu <leo.liu@amd.com> | 2017-02-21 10:36:15 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-05-24 17:41:41 -0400 |
commit | 8ace845ff0e8fc610686c0fa12ec05130fbf1f6b (patch) | |
tree | 0c74df3fa2873c57e9d5a0ff4efafd6ada9cc54c /drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |
parent | 101c6fee53f6a73c0d044cf890cd8b1b07cf5801 (diff) |
drm/amdgpu: add vcn enc ring type and functions
Add the ring function callbacks for the encode rings.
Signed-off-by: Leo Liu <leo.liu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index b8f4e7713921..e15a81ffa2ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |||
@@ -38,6 +38,7 @@ | |||
38 | static int vcn_v1_0_start(struct amdgpu_device *adev); | 38 | static int vcn_v1_0_start(struct amdgpu_device *adev); |
39 | static int vcn_v1_0_stop(struct amdgpu_device *adev); | 39 | static int vcn_v1_0_stop(struct amdgpu_device *adev); |
40 | static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); | 40 | static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); |
41 | static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); | ||
41 | static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev); | 42 | static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev); |
42 | 43 | ||
43 | /** | 44 | /** |
@@ -54,6 +55,7 @@ static int vcn_v1_0_early_init(void *handle) | |||
54 | adev->vcn.num_enc_rings = 2; | 55 | adev->vcn.num_enc_rings = 2; |
55 | 56 | ||
56 | vcn_v1_0_set_dec_ring_funcs(adev); | 57 | vcn_v1_0_set_dec_ring_funcs(adev); |
58 | vcn_v1_0_set_enc_ring_funcs(adev); | ||
57 | vcn_v1_0_set_irq_funcs(adev); | 59 | vcn_v1_0_set_irq_funcs(adev); |
58 | 60 | ||
59 | return 0; | 61 | return 0; |
@@ -688,6 +690,141 @@ static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring, | |||
688 | vcn_v1_0_dec_vm_reg_wait(ring, data0, data1, mask); | 690 | vcn_v1_0_dec_vm_reg_wait(ring, data0, data1, mask); |
689 | } | 691 | } |
690 | 692 | ||
693 | /** | ||
694 | * vcn_v1_0_enc_ring_get_rptr - get enc read pointer | ||
695 | * | ||
696 | * @ring: amdgpu_ring pointer | ||
697 | * | ||
698 | * Returns the current hardware enc read pointer | ||
699 | */ | ||
700 | static uint64_t vcn_v1_0_enc_ring_get_rptr(struct amdgpu_ring *ring) | ||
701 | { | ||
702 | struct amdgpu_device *adev = ring->adev; | ||
703 | |||
704 | if (ring == &adev->vcn.ring_enc[0]) | ||
705 | return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_RPTR)); | ||
706 | else | ||
707 | return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_RPTR2)); | ||
708 | } | ||
709 | |||
710 | /** | ||
711 | * vcn_v1_0_enc_ring_get_wptr - get enc write pointer | ||
712 | * | ||
713 | * @ring: amdgpu_ring pointer | ||
714 | * | ||
715 | * Returns the current hardware enc write pointer | ||
716 | */ | ||
717 | static uint64_t vcn_v1_0_enc_ring_get_wptr(struct amdgpu_ring *ring) | ||
718 | { | ||
719 | struct amdgpu_device *adev = ring->adev; | ||
720 | |||
721 | if (ring == &adev->vcn.ring_enc[0]) | ||
722 | return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR)); | ||
723 | else | ||
724 | return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR2)); | ||
725 | } | ||
726 | |||
727 | /** | ||
728 | * vcn_v1_0_enc_ring_set_wptr - set enc write pointer | ||
729 | * | ||
730 | * @ring: amdgpu_ring pointer | ||
731 | * | ||
732 | * Commits the enc write pointer to the hardware | ||
733 | */ | ||
734 | static void vcn_v1_0_enc_ring_set_wptr(struct amdgpu_ring *ring) | ||
735 | { | ||
736 | struct amdgpu_device *adev = ring->adev; | ||
737 | |||
738 | if (ring == &adev->vcn.ring_enc[0]) | ||
739 | WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR), | ||
740 | lower_32_bits(ring->wptr)); | ||
741 | else | ||
742 | WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR2), | ||
743 | lower_32_bits(ring->wptr)); | ||
744 | } | ||
745 | |||
746 | /** | ||
747 | * vcn_v1_0_enc_ring_emit_fence - emit an enc fence & trap command | ||
748 | * | ||
749 | * @ring: amdgpu_ring pointer | ||
750 | * @fence: fence to emit | ||
751 | * | ||
752 | * Write enc a fence and a trap command to the ring. | ||
753 | */ | ||
754 | static void vcn_v1_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, | ||
755 | u64 seq, unsigned flags) | ||
756 | { | ||
757 | WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); | ||
758 | |||
759 | amdgpu_ring_write(ring, VCN_ENC_CMD_FENCE); | ||
760 | amdgpu_ring_write(ring, addr); | ||
761 | amdgpu_ring_write(ring, upper_32_bits(addr)); | ||
762 | amdgpu_ring_write(ring, seq); | ||
763 | amdgpu_ring_write(ring, VCN_ENC_CMD_TRAP); | ||
764 | } | ||
765 | |||
766 | static void vcn_v1_0_enc_ring_insert_end(struct amdgpu_ring *ring) | ||
767 | { | ||
768 | amdgpu_ring_write(ring, VCN_ENC_CMD_END); | ||
769 | } | ||
770 | |||
771 | /** | ||
772 | * vcn_v1_0_enc_ring_emit_ib - enc execute indirect buffer | ||
773 | * | ||
774 | * @ring: amdgpu_ring pointer | ||
775 | * @ib: indirect buffer to execute | ||
776 | * | ||
777 | * Write enc ring commands to execute the indirect buffer | ||
778 | */ | ||
779 | static void vcn_v1_0_enc_ring_emit_ib(struct amdgpu_ring *ring, | ||
780 | struct amdgpu_ib *ib, unsigned int vm_id, bool ctx_switch) | ||
781 | { | ||
782 | amdgpu_ring_write(ring, VCN_ENC_CMD_IB); | ||
783 | amdgpu_ring_write(ring, vm_id); | ||
784 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | ||
785 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); | ||
786 | amdgpu_ring_write(ring, ib->length_dw); | ||
787 | } | ||
788 | |||
789 | static void vcn_v1_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring, | ||
790 | unsigned int vm_id, uint64_t pd_addr) | ||
791 | { | ||
792 | struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub]; | ||
793 | uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id); | ||
794 | unsigned eng = ring->vm_inv_eng; | ||
795 | |||
796 | pd_addr = pd_addr | 0x1; /* valid bit */ | ||
797 | /* now only use physical base address of PDE and valid */ | ||
798 | BUG_ON(pd_addr & 0xFFFF00000000003EULL); | ||
799 | |||
800 | amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE); | ||
801 | amdgpu_ring_write(ring, | ||
802 | (hub->ctx0_ptb_addr_hi32 + vm_id * 2) << 2); | ||
803 | amdgpu_ring_write(ring, upper_32_bits(pd_addr)); | ||
804 | |||
805 | amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE); | ||
806 | amdgpu_ring_write(ring, | ||
807 | (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2); | ||
808 | amdgpu_ring_write(ring, lower_32_bits(pd_addr)); | ||
809 | |||
810 | amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WAIT); | ||
811 | amdgpu_ring_write(ring, | ||
812 | (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2); | ||
813 | amdgpu_ring_write(ring, 0xffffffff); | ||
814 | amdgpu_ring_write(ring, lower_32_bits(pd_addr)); | ||
815 | |||
816 | /* flush TLB */ | ||
817 | amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE); | ||
818 | amdgpu_ring_write(ring, (hub->vm_inv_eng0_req + eng) << 2); | ||
819 | amdgpu_ring_write(ring, req); | ||
820 | |||
821 | /* wait for flush */ | ||
822 | amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WAIT); | ||
823 | amdgpu_ring_write(ring, (hub->vm_inv_eng0_ack + eng) << 2); | ||
824 | amdgpu_ring_write(ring, 1 << vm_id); | ||
825 | amdgpu_ring_write(ring, 1 << vm_id); | ||
826 | } | ||
827 | |||
691 | static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev, | 828 | static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev, |
692 | struct amdgpu_irq_src *source, | 829 | struct amdgpu_irq_src *source, |
693 | unsigned type, | 830 | unsigned type, |
@@ -755,12 +892,45 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { | |||
755 | .end_use = amdgpu_vcn_ring_end_use, | 892 | .end_use = amdgpu_vcn_ring_end_use, |
756 | }; | 893 | }; |
757 | 894 | ||
895 | static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = { | ||
896 | .type = AMDGPU_RING_TYPE_VCN_ENC, | ||
897 | .align_mask = 0x3f, | ||
898 | .nop = VCN_ENC_CMD_NO_OP, | ||
899 | .support_64bit_ptrs = false, | ||
900 | .get_rptr = vcn_v1_0_enc_ring_get_rptr, | ||
901 | .get_wptr = vcn_v1_0_enc_ring_get_wptr, | ||
902 | .set_wptr = vcn_v1_0_enc_ring_set_wptr, | ||
903 | .emit_frame_size = | ||
904 | 17 * AMDGPU_MAX_VMHUBS + /* vcn_v1_0_enc_ring_emit_vm_flush */ | ||
905 | 5 + 5 + /* vcn_v1_0_enc_ring_emit_fence x2 vm fence */ | ||
906 | 1, /* vcn_v1_0_enc_ring_insert_end */ | ||
907 | .emit_ib_size = 5, /* vcn_v1_0_enc_ring_emit_ib */ | ||
908 | .emit_ib = vcn_v1_0_enc_ring_emit_ib, | ||
909 | .emit_fence = vcn_v1_0_enc_ring_emit_fence, | ||
910 | .emit_vm_flush = vcn_v1_0_enc_ring_emit_vm_flush, | ||
911 | .insert_nop = amdgpu_ring_insert_nop, | ||
912 | .insert_end = vcn_v1_0_enc_ring_insert_end, | ||
913 | .pad_ib = amdgpu_ring_generic_pad_ib, | ||
914 | .begin_use = amdgpu_vcn_ring_begin_use, | ||
915 | .end_use = amdgpu_vcn_ring_end_use, | ||
916 | }; | ||
917 | |||
758 | static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) | 918 | static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) |
759 | { | 919 | { |
760 | adev->vcn.ring_dec.funcs = &vcn_v1_0_dec_ring_vm_funcs; | 920 | adev->vcn.ring_dec.funcs = &vcn_v1_0_dec_ring_vm_funcs; |
761 | DRM_INFO("VCN decode is enabled in VM mode\n"); | 921 | DRM_INFO("VCN decode is enabled in VM mode\n"); |
762 | } | 922 | } |
763 | 923 | ||
924 | static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev) | ||
925 | { | ||
926 | int i; | ||
927 | |||
928 | for (i = 0; i < adev->vcn.num_enc_rings; ++i) | ||
929 | adev->vcn.ring_enc[i].funcs = &vcn_v1_0_enc_ring_vm_funcs; | ||
930 | |||
931 | DRM_INFO("VCN encode is enabled in VM mode\n"); | ||
932 | } | ||
933 | |||
764 | static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = { | 934 | static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = { |
765 | .set = vcn_v1_0_set_interrupt_state, | 935 | .set = vcn_v1_0_set_interrupt_state, |
766 | .process = vcn_v1_0_process_interrupt, | 936 | .process = vcn_v1_0_process_interrupt, |