aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
diff options
context:
space:
mode:
authorLeo Liu <leo.liu@amd.com>2017-02-21 10:36:15 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-05-24 17:41:41 -0400
commit8ace845ff0e8fc610686c0fa12ec05130fbf1f6b (patch)
tree0c74df3fa2873c57e9d5a0ff4efafd6ada9cc54c /drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
parent101c6fee53f6a73c0d044cf890cd8b1b07cf5801 (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.c170
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 @@
38static int vcn_v1_0_start(struct amdgpu_device *adev); 38static int vcn_v1_0_start(struct amdgpu_device *adev);
39static int vcn_v1_0_stop(struct amdgpu_device *adev); 39static int vcn_v1_0_stop(struct amdgpu_device *adev);
40static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); 40static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
41static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);
41static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev); 42static 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 */
700static 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 */
717static 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 */
734static 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 */
754static 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
766static 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 */
779static 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
789static 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
691static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev, 828static 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
895static 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
758static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) 918static 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
924static 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
764static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = { 934static 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,