diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 290 |
1 files changed, 170 insertions, 120 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index e9282415c24f..eae90922fdbe 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |||
@@ -37,6 +37,11 @@ | |||
37 | 37 | ||
38 | #include "ivsrcid/vcn/irqsrcs_vcn_1_0.h" | 38 | #include "ivsrcid/vcn/irqsrcs_vcn_1_0.h" |
39 | 39 | ||
40 | #define mmUVD_RBC_XX_IB_REG_CHECK 0x05ab | ||
41 | #define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX 1 | ||
42 | #define mmUVD_REG_XX_MASK 0x05ac | ||
43 | #define mmUVD_REG_XX_MASK_BASE_IDX 1 | ||
44 | |||
40 | static int vcn_v1_0_stop(struct amdgpu_device *adev); | 45 | static int vcn_v1_0_stop(struct amdgpu_device *adev); |
41 | static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); | 46 | static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); |
42 | static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); | 47 | static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); |
@@ -320,6 +325,24 @@ static void vcn_v1_0_mc_resume_spg_mode(struct amdgpu_device *adev) | |||
320 | adev->gfx.config.gb_addr_config); | 325 | adev->gfx.config.gb_addr_config); |
321 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG, | 326 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG, |
322 | adev->gfx.config.gb_addr_config); | 327 | adev->gfx.config.gb_addr_config); |
328 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_UV_ADDR_CONFIG, | ||
329 | adev->gfx.config.gb_addr_config); | ||
330 | WREG32_SOC15(UVD, 0, mmUVD_MIF_CURR_ADDR_CONFIG, | ||
331 | adev->gfx.config.gb_addr_config); | ||
332 | WREG32_SOC15(UVD, 0, mmUVD_MIF_CURR_UV_ADDR_CONFIG, | ||
333 | adev->gfx.config.gb_addr_config); | ||
334 | WREG32_SOC15(UVD, 0, mmUVD_MIF_RECON1_ADDR_CONFIG, | ||
335 | adev->gfx.config.gb_addr_config); | ||
336 | WREG32_SOC15(UVD, 0, mmUVD_MIF_RECON1_UV_ADDR_CONFIG, | ||
337 | adev->gfx.config.gb_addr_config); | ||
338 | WREG32_SOC15(UVD, 0, mmUVD_MIF_REF_ADDR_CONFIG, | ||
339 | adev->gfx.config.gb_addr_config); | ||
340 | WREG32_SOC15(UVD, 0, mmUVD_MIF_REF_UV_ADDR_CONFIG, | ||
341 | adev->gfx.config.gb_addr_config); | ||
342 | WREG32_SOC15(UVD, 0, mmUVD_JPEG_ADDR_CONFIG, | ||
343 | adev->gfx.config.gb_addr_config); | ||
344 | WREG32_SOC15(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG, | ||
345 | adev->gfx.config.gb_addr_config); | ||
323 | } | 346 | } |
324 | 347 | ||
325 | static void vcn_v1_0_mc_resume_dpg_mode(struct amdgpu_device *adev) | 348 | static void vcn_v1_0_mc_resume_dpg_mode(struct amdgpu_device *adev) |
@@ -371,16 +394,27 @@ static void vcn_v1_0_mc_resume_dpg_mode(struct amdgpu_device *adev) | |||
371 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE, | 394 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE, |
372 | 0xFFFFFFFF, 0); | 395 | 0xFFFFFFFF, 0); |
373 | 396 | ||
397 | /* VCN global tiling registers */ | ||
374 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_ADDR_CONFIG, | 398 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_ADDR_CONFIG, |
375 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | 399 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); |
376 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG, | 400 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG, |
377 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | 401 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); |
378 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG, | 402 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG, |
379 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | 403 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); |
380 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_JPEG_ADDR_CONFIG, | 404 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DBW_UV_ADDR_CONFIG, |
381 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | 405 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); |
382 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG, | 406 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_CURR_ADDR_CONFIG, |
383 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | 407 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); |
408 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_CURR_UV_ADDR_CONFIG, | ||
409 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | ||
410 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_RECON1_ADDR_CONFIG, | ||
411 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | ||
412 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_RECON1_UV_ADDR_CONFIG, | ||
413 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | ||
414 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_REF_ADDR_CONFIG, | ||
415 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | ||
416 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_REF_UV_ADDR_CONFIG, | ||
417 | adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0); | ||
384 | } | 418 | } |
385 | 419 | ||
386 | /** | 420 | /** |
@@ -743,41 +777,24 @@ static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev) | |||
743 | lmi_swap_cntl = 0; | 777 | lmi_swap_cntl = 0; |
744 | 778 | ||
745 | vcn_1_0_disable_static_power_gating(adev); | 779 | vcn_1_0_disable_static_power_gating(adev); |
780 | |||
781 | tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY; | ||
782 | WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp); | ||
783 | |||
746 | /* disable clock gating */ | 784 | /* disable clock gating */ |
747 | vcn_v1_0_disable_clock_gating(adev); | 785 | vcn_v1_0_disable_clock_gating(adev); |
748 | 786 | ||
749 | vcn_v1_0_mc_resume_spg_mode(adev); | ||
750 | |||
751 | /* disable interupt */ | 787 | /* disable interupt */ |
752 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0, | 788 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0, |
753 | ~UVD_MASTINT_EN__VCPU_EN_MASK); | 789 | ~UVD_MASTINT_EN__VCPU_EN_MASK); |
754 | 790 | ||
755 | /* stall UMC and register bus before resetting VCPU */ | ||
756 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | ||
757 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
758 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
759 | mdelay(1); | ||
760 | |||
761 | /* put LMI, VCPU, RBC etc... into reset */ | ||
762 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | ||
763 | UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
764 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
765 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
766 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
767 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
768 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
769 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
770 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); | ||
771 | mdelay(5); | ||
772 | |||
773 | /* initialize VCN memory controller */ | 791 | /* initialize VCN memory controller */ |
774 | WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, | 792 | tmp = RREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL); |
775 | (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | 793 | WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, tmp | |
776 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | 794 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | |
777 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | 795 | UVD_LMI_CTRL__MASK_MC_URGENT_MASK | |
778 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | 796 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | |
779 | UVD_LMI_CTRL__REQ_MODE_MASK | | 797 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); |
780 | 0x00100000L); | ||
781 | 798 | ||
782 | #ifdef __BIG_ENDIAN | 799 | #ifdef __BIG_ENDIAN |
783 | /* swap (8 in 32) RB and IB */ | 800 | /* swap (8 in 32) RB and IB */ |
@@ -785,29 +802,49 @@ static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev) | |||
785 | #endif | 802 | #endif |
786 | WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); | 803 | WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); |
787 | 804 | ||
788 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0, 0x40c2040); | 805 | tmp = RREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL); |
789 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA1, 0x0); | 806 | tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; |
790 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0, 0x40c2040); | 807 | tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; |
791 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB1, 0x0); | 808 | WREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL, tmp); |
792 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_ALU, 0); | 809 | |
793 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX, 0x88); | 810 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0, |
811 | ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | | ||
812 | (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | | ||
813 | (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | | ||
814 | (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); | ||
815 | |||
816 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0, | ||
817 | ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | | ||
818 | (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | | ||
819 | (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | | ||
820 | (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); | ||
794 | 821 | ||
795 | /* take all subblocks out of reset, except VCPU */ | 822 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX, |
796 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | 823 | ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | |
797 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | 824 | (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | |
798 | mdelay(5); | 825 | (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); |
826 | |||
827 | vcn_v1_0_mc_resume_spg_mode(adev); | ||
828 | |||
829 | WREG32_SOC15(UVD, 0, mmUVD_REG_XX_MASK, 0x10); | ||
830 | WREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK, | ||
831 | RREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK) | 0x3); | ||
799 | 832 | ||
800 | /* enable VCPU clock */ | 833 | /* enable VCPU clock */ |
801 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, | 834 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK); |
802 | UVD_VCPU_CNTL__CLK_EN_MASK); | 835 | |
836 | /* boot up the VCPU */ | ||
837 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0, | ||
838 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
803 | 839 | ||
804 | /* enable UMC */ | 840 | /* enable UMC */ |
805 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, | 841 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, |
806 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | 842 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); |
807 | 843 | ||
808 | /* boot up the VCPU */ | 844 | tmp = RREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET); |
809 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, 0); | 845 | tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; |
810 | mdelay(10); | 846 | tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; |
847 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, tmp); | ||
811 | 848 | ||
812 | for (i = 0; i < 10; ++i) { | 849 | for (i = 0; i < 10; ++i) { |
813 | uint32_t status; | 850 | uint32_t status; |
@@ -839,24 +876,22 @@ static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev) | |||
839 | } | 876 | } |
840 | /* enable master interrupt */ | 877 | /* enable master interrupt */ |
841 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), | 878 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), |
842 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | 879 | UVD_MASTINT_EN__VCPU_EN_MASK, ~UVD_MASTINT_EN__VCPU_EN_MASK); |
843 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); | ||
844 | 880 | ||
845 | /* enable system interrupt for JRBC, TODO: move to set interrupt*/ | 881 | /* enable system interrupt for JRBC, TODO: move to set interrupt*/ |
846 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SYS_INT_EN), | 882 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SYS_INT_EN), |
847 | UVD_SYS_INT_EN__UVD_JRBC_EN_MASK, | 883 | UVD_SYS_INT_EN__UVD_JRBC_EN_MASK, |
848 | ~UVD_SYS_INT_EN__UVD_JRBC_EN_MASK); | 884 | ~UVD_SYS_INT_EN__UVD_JRBC_EN_MASK); |
849 | 885 | ||
850 | /* clear the bit 4 of VCN_STATUS */ | 886 | /* clear the busy bit of UVD_STATUS */ |
851 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0, | 887 | tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) & ~UVD_STATUS__UVD_BUSY; |
852 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); | 888 | WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp); |
853 | 889 | ||
854 | /* force RBC into idle state */ | 890 | /* force RBC into idle state */ |
855 | rb_bufsz = order_base_2(ring->ring_size); | 891 | rb_bufsz = order_base_2(ring->ring_size); |
856 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); | 892 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); |
857 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); | 893 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); |
858 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | 894 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); |
859 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); | ||
860 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); | 895 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); |
861 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); | 896 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); |
862 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp); | 897 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp); |
@@ -923,7 +958,7 @@ static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev) | |||
923 | static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev) | 958 | static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev) |
924 | { | 959 | { |
925 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; | 960 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; |
926 | uint32_t rb_bufsz, tmp, reg_data; | 961 | uint32_t rb_bufsz, tmp; |
927 | uint32_t lmi_swap_cntl; | 962 | uint32_t lmi_swap_cntl; |
928 | 963 | ||
929 | /* disable byte swapping */ | 964 | /* disable byte swapping */ |
@@ -932,47 +967,33 @@ static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev) | |||
932 | vcn_1_0_enable_static_power_gating(adev); | 967 | vcn_1_0_enable_static_power_gating(adev); |
933 | 968 | ||
934 | /* enable dynamic power gating mode */ | 969 | /* enable dynamic power gating mode */ |
935 | reg_data = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS); | 970 | tmp = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS); |
936 | reg_data |= UVD_POWER_STATUS__UVD_PG_MODE_MASK; | 971 | tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK; |
937 | reg_data |= UVD_POWER_STATUS__UVD_PG_EN_MASK; | 972 | tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK; |
938 | WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, reg_data); | 973 | WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, tmp); |
939 | 974 | ||
940 | /* enable clock gating */ | 975 | /* enable clock gating */ |
941 | vcn_v1_0_clock_gating_dpg_mode(adev, 0); | 976 | vcn_v1_0_clock_gating_dpg_mode(adev, 0); |
942 | 977 | ||
943 | /* enable VCPU clock */ | 978 | /* enable VCPU clock */ |
944 | reg_data = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); | 979 | tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); |
945 | reg_data |= UVD_VCPU_CNTL__CLK_EN_MASK; | 980 | tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; |
946 | reg_data |= UVD_VCPU_CNTL__MIF_WR_LOW_THRESHOLD_BP_MASK; | 981 | tmp |= UVD_VCPU_CNTL__MIF_WR_LOW_THRESHOLD_BP_MASK; |
947 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CNTL, reg_data, 0xFFFFFFFF, 0); | 982 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CNTL, tmp, 0xFFFFFFFF, 0); |
948 | 983 | ||
949 | /* disable interupt */ | 984 | /* disable interupt */ |
950 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MASTINT_EN, | 985 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MASTINT_EN, |
951 | 0, UVD_MASTINT_EN__VCPU_EN_MASK, 0); | 986 | 0, UVD_MASTINT_EN__VCPU_EN_MASK, 0); |
952 | 987 | ||
953 | /* stall UMC and register bus before resetting VCPU */ | ||
954 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL2, | ||
955 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0); | ||
956 | |||
957 | /* put LMI, VCPU, RBC etc... into reset */ | ||
958 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_SOFT_RESET, | ||
959 | UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
960 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
961 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
962 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
963 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
964 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
965 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
966 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK, | ||
967 | 0xFFFFFFFF, 0); | ||
968 | |||
969 | /* initialize VCN memory controller */ | 988 | /* initialize VCN memory controller */ |
970 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL, | 989 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL, |
971 | (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | 990 | (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | |
972 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | 991 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | |
973 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | 992 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | |
974 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | 993 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | |
975 | UVD_LMI_CTRL__REQ_MODE_MASK | | 994 | UVD_LMI_CTRL__REQ_MODE_MASK | |
995 | UVD_LMI_CTRL__CRC_RESET_MASK | | ||
996 | UVD_LMI_CTRL__MASK_MC_URGENT_MASK | | ||
976 | 0x00100000L, 0xFFFFFFFF, 0); | 997 | 0x00100000L, 0xFFFFFFFF, 0); |
977 | 998 | ||
978 | #ifdef __BIG_ENDIAN | 999 | #ifdef __BIG_ENDIAN |
@@ -981,45 +1002,54 @@ static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev) | |||
981 | #endif | 1002 | #endif |
982 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl, 0xFFFFFFFF, 0); | 1003 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl, 0xFFFFFFFF, 0); |
983 | 1004 | ||
984 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUXA0, 0x40c2040, 0xFFFFFFFF, 0); | 1005 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_CNTL, |
985 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUXA1, 0x0, 0xFFFFFFFF, 0); | 1006 | 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0xFFFFFFFF, 0); |
986 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUXB0, 0x40c2040, 0xFFFFFFFF, 0); | ||
987 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUXB1, 0x0, 0xFFFFFFFF, 0); | ||
988 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_ALU, 0, 0xFFFFFFFF, 0); | ||
989 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUX, 0x88, 0xFFFFFFFF, 0); | ||
990 | 1007 | ||
991 | vcn_v1_0_mc_resume_dpg_mode(adev); | 1008 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUXA0, |
1009 | ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | | ||
1010 | (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | | ||
1011 | (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | | ||
1012 | (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0xFFFFFFFF, 0); | ||
992 | 1013 | ||
993 | /* take all subblocks out of reset, except VCPU */ | 1014 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUXB0, |
994 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_SOFT_RESET, | 1015 | ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | |
995 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK, 0xFFFFFFFF, 0); | 1016 | (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | |
1017 | (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | | ||
1018 | (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0xFFFFFFFF, 0); | ||
996 | 1019 | ||
997 | /* enable VCPU clock */ | 1020 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUX, |
998 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CNTL, | 1021 | ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | |
999 | UVD_VCPU_CNTL__CLK_EN_MASK, 0xFFFFFFFF, 0); | 1022 | (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | |
1023 | (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0xFFFFFFFF, 0); | ||
1000 | 1024 | ||
1001 | /* enable UMC */ | 1025 | vcn_v1_0_mc_resume_dpg_mode(adev); |
1002 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL2, | 1026 | |
1003 | 0, UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0); | 1027 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_REG_XX_MASK, 0x10, 0xFFFFFFFF, 0); |
1028 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK, 0x3, 0xFFFFFFFF, 0); | ||
1004 | 1029 | ||
1005 | /* boot up the VCPU */ | 1030 | /* boot up the VCPU */ |
1006 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_SOFT_RESET, 0, 0xFFFFFFFF, 0); | 1031 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_SOFT_RESET, 0, 0xFFFFFFFF, 0); |
1007 | 1032 | ||
1033 | /* enable UMC */ | ||
1034 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL2, | ||
1035 | 0x1F << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT, | ||
1036 | 0xFFFFFFFF, 0); | ||
1037 | |||
1008 | /* enable master interrupt */ | 1038 | /* enable master interrupt */ |
1009 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MASTINT_EN, | 1039 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MASTINT_EN, |
1010 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | 1040 | UVD_MASTINT_EN__VCPU_EN_MASK, UVD_MASTINT_EN__VCPU_EN_MASK, 0); |
1011 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), 0); | ||
1012 | 1041 | ||
1013 | vcn_v1_0_clock_gating_dpg_mode(adev, 1); | 1042 | vcn_v1_0_clock_gating_dpg_mode(adev, 1); |
1014 | /* setup mmUVD_LMI_CTRL */ | 1043 | /* setup mmUVD_LMI_CTRL */ |
1015 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL, | 1044 | WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL, |
1016 | (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | 1045 | (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | |
1017 | UVD_LMI_CTRL__CRC_RESET_MASK | | 1046 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | |
1018 | UVD_LMI_CTRL__MASK_MC_URGENT_MASK | | 1047 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | |
1019 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | 1048 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | |
1020 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | 1049 | UVD_LMI_CTRL__REQ_MODE_MASK | |
1021 | (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | 1050 | UVD_LMI_CTRL__CRC_RESET_MASK | |
1022 | 0x00100000L), 0xFFFFFFFF, 1); | 1051 | UVD_LMI_CTRL__MASK_MC_URGENT_MASK | |
1052 | 0x00100000L, 0xFFFFFFFF, 1); | ||
1023 | 1053 | ||
1024 | tmp = adev->gfx.config.gb_addr_config; | 1054 | tmp = adev->gfx.config.gb_addr_config; |
1025 | /* setup VCN global tiling registers */ | 1055 | /* setup VCN global tiling registers */ |
@@ -1035,7 +1065,6 @@ static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev) | |||
1035 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); | 1065 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); |
1036 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); | 1066 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); |
1037 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | 1067 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); |
1038 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); | ||
1039 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); | 1068 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); |
1040 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); | 1069 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); |
1041 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp); | 1070 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp); |
@@ -1095,28 +1124,39 @@ static int vcn_v1_0_start(struct amdgpu_device *adev) | |||
1095 | */ | 1124 | */ |
1096 | static int vcn_v1_0_stop_spg_mode(struct amdgpu_device *adev) | 1125 | static int vcn_v1_0_stop_spg_mode(struct amdgpu_device *adev) |
1097 | { | 1126 | { |
1098 | /* force RBC into idle state */ | 1127 | int ret_code, tmp; |
1099 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, 0x11010101); | ||
1100 | 1128 | ||
1101 | /* Stall UMC and register bus before resetting VCPU */ | 1129 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, ret_code); |
1102 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | 1130 | |
1103 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | 1131 | tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | |
1104 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | 1132 | UVD_LMI_STATUS__READ_CLEAN_MASK | |
1105 | mdelay(1); | 1133 | UVD_LMI_STATUS__WRITE_CLEAN_MASK | |
1134 | UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; | ||
1135 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_LMI_STATUS, tmp, tmp, ret_code); | ||
1106 | 1136 | ||
1107 | /* put VCPU into reset */ | 1137 | /* put VCPU into reset */ |
1108 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | 1138 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), |
1109 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | 1139 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK, |
1110 | mdelay(5); | 1140 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); |
1141 | |||
1142 | tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | | ||
1143 | UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; | ||
1144 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_LMI_STATUS, tmp, tmp, ret_code); | ||
1111 | 1145 | ||
1112 | /* disable VCPU clock */ | 1146 | /* disable VCPU clock */ |
1113 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, 0x0); | 1147 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL), 0, |
1148 | ~UVD_VCPU_CNTL__CLK_EN_MASK); | ||
1114 | 1149 | ||
1115 | /* Unstall UMC and register bus */ | 1150 | /* reset LMI UMC/LMI */ |
1116 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, | 1151 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), |
1117 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | 1152 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK, |
1153 | ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); | ||
1154 | |||
1155 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), | ||
1156 | UVD_SOFT_RESET__LMI_SOFT_RESET_MASK, | ||
1157 | ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK); | ||
1118 | 1158 | ||
1119 | WREG32_SOC15(VCN, 0, mmUVD_STATUS, 0); | 1159 | WREG32_SOC15(UVD, 0, mmUVD_STATUS, 0); |
1120 | 1160 | ||
1121 | vcn_v1_0_enable_clock_gating(adev); | 1161 | vcn_v1_0_enable_clock_gating(adev); |
1122 | vcn_1_0_enable_static_power_gating(adev); | 1162 | vcn_1_0_enable_static_power_gating(adev); |
@@ -1125,13 +1165,23 @@ static int vcn_v1_0_stop_spg_mode(struct amdgpu_device *adev) | |||
1125 | 1165 | ||
1126 | static int vcn_v1_0_stop_dpg_mode(struct amdgpu_device *adev) | 1166 | static int vcn_v1_0_stop_dpg_mode(struct amdgpu_device *adev) |
1127 | { | 1167 | { |
1128 | int ret_code; | 1168 | int ret_code = 0; |
1129 | 1169 | ||
1130 | /* Wait for power status to be UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF */ | 1170 | /* Wait for power status to be UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF */ |
1131 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, | 1171 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, |
1132 | UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, | 1172 | UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, |
1133 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); | 1173 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); |
1134 | 1174 | ||
1175 | if (!ret_code) { | ||
1176 | int tmp = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF; | ||
1177 | /* wait for read ptr to be equal to write ptr */ | ||
1178 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code); | ||
1179 | |||
1180 | SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, | ||
1181 | UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, | ||
1182 | UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); | ||
1183 | } | ||
1184 | |||
1135 | /* disable dynamic power gating mode */ | 1185 | /* disable dynamic power gating mode */ |
1136 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0, | 1186 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0, |
1137 | ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); | 1187 | ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); |