Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/cik: restructure rlc setup

Restructure rlc setup to handle clock and power
gating.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+56 -31
+54 -30
drivers/gpu/drm/radeon/cik.c
··· 60 60 extern void si_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); 61 61 extern void si_rlc_fini(struct radeon_device *rdev); 62 62 extern int si_rlc_init(struct radeon_device *rdev); 63 + extern void si_rlc_reset(struct radeon_device *rdev); 63 64 static void cik_rlc_stop(struct radeon_device *rdev); 64 65 static void cik_pcie_gen3_enable(struct radeon_device *rdev); 65 66 static void cik_program_aspm(struct radeon_device *rdev); ··· 4729 4728 * variety of functions, the most important of which is 4730 4729 * the interrupt controller. 4731 4730 */ 4732 - /** 4733 - * cik_rlc_stop - stop the RLC ME 4734 - * 4735 - * @rdev: radeon_device pointer 4736 - * 4737 - * Halt the RLC ME (MicroEngine) (CIK). 4738 - */ 4739 - static void cik_rlc_stop(struct radeon_device *rdev) 4731 + static void cik_enable_gui_idle_interrupt(struct radeon_device *rdev, 4732 + bool enable) 4740 4733 { 4741 - int i, j, k; 4742 - u32 mask, tmp; 4734 + u32 tmp = RREG32(CP_INT_CNTL_RING0); 4743 4735 4744 - tmp = RREG32(CP_INT_CNTL_RING0); 4745 - tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 4736 + if (enable) 4737 + tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 4738 + else 4739 + tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 4746 4740 WREG32(CP_INT_CNTL_RING0, tmp); 4741 + } 4747 4742 4748 - RREG32(CB_CGTT_SCLK_CTRL); 4749 - RREG32(CB_CGTT_SCLK_CTRL); 4750 - RREG32(CB_CGTT_SCLK_CTRL); 4751 - RREG32(CB_CGTT_SCLK_CTRL); 4743 + static void cik_enable_lbpw(struct radeon_device *rdev, bool enable) 4744 + { 4745 + u32 tmp; 4752 4746 4753 - tmp = RREG32(RLC_CGCG_CGLS_CTRL) & 0xfffffffc; 4754 - WREG32(RLC_CGCG_CGLS_CTRL, tmp); 4747 + tmp = RREG32(RLC_LB_CNTL); 4748 + if (enable) 4749 + tmp |= LOAD_BALANCE_ENABLE; 4750 + else 4751 + tmp &= ~LOAD_BALANCE_ENABLE; 4752 + WREG32(RLC_LB_CNTL, tmp); 4753 + } 4755 4754 4756 - WREG32(RLC_CNTL, 0); 4755 + static void cik_wait_for_rlc_serdes(struct radeon_device *rdev) 4756 + { 4757 + u32 i, j, k; 4758 + u32 mask; 4757 4759 4758 4760 for (i = 0; i < rdev->config.cik.max_shader_engines; i++) { 4759 4761 for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) { ··· 4779 4775 } 4780 4776 4781 4777 /** 4778 + * cik_rlc_stop - stop the RLC ME 4779 + * 4780 + * @rdev: radeon_device pointer 4781 + * 4782 + * Halt the RLC ME (MicroEngine) (CIK). 4783 + */ 4784 + static void cik_rlc_stop(struct radeon_device *rdev) 4785 + { 4786 + u32 tmp; 4787 + 4788 + cik_enable_gui_idle_interrupt(rdev, false); 4789 + 4790 + RREG32(CB_CGTT_SCLK_CTRL); 4791 + RREG32(CB_CGTT_SCLK_CTRL); 4792 + RREG32(CB_CGTT_SCLK_CTRL); 4793 + RREG32(CB_CGTT_SCLK_CTRL); 4794 + 4795 + tmp = RREG32(RLC_CGCG_CGLS_CTRL) & 0xfffffffc; 4796 + WREG32(RLC_CGCG_CGLS_CTRL, tmp); 4797 + 4798 + WREG32(RLC_CNTL, 0); 4799 + 4800 + cik_wait_for_rlc_serdes(rdev); 4801 + } 4802 + 4803 + /** 4782 4804 * cik_rlc_start - start the RLC ME 4783 4805 * 4784 4806 * @rdev: radeon_device pointer ··· 4813 4783 */ 4814 4784 static void cik_rlc_start(struct radeon_device *rdev) 4815 4785 { 4816 - u32 tmp; 4817 - 4818 4786 WREG32(RLC_CNTL, RLC_ENABLE); 4819 4787 4820 - tmp = RREG32(CP_INT_CNTL_RING0); 4821 - tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 4822 - WREG32(CP_INT_CNTL_RING0, tmp); 4788 + cik_enable_gui_idle_interrupt(rdev, true); 4823 4789 4824 4790 udelay(50); 4825 4791 } ··· 4853 4827 4854 4828 cik_rlc_stop(rdev); 4855 4829 4856 - WREG32(GRBM_SOFT_RESET, SOFT_RESET_RLC); 4857 - RREG32(GRBM_SOFT_RESET); 4858 - udelay(50); 4859 - WREG32(GRBM_SOFT_RESET, 0); 4860 - RREG32(GRBM_SOFT_RESET); 4861 - udelay(50); 4830 + si_rlc_reset(rdev); 4862 4831 4863 4832 WREG32(RLC_LB_CNTR_INIT, 0); 4864 4833 WREG32(RLC_LB_CNTR_MAX, 0x00008000); ··· 4871 4850 for (i = 0; i < size; i++) 4872 4851 WREG32(RLC_GPM_UCODE_DATA, be32_to_cpup(fw_data++)); 4873 4852 WREG32(RLC_GPM_UCODE_ADDR, 0); 4853 + 4854 + /* XXX - find out what chips support lbpw */ 4855 + cik_enable_lbpw(rdev, false); 4874 4856 4875 4857 /* XXX */ 4876 4858 clear_state_info[0] = 0;//upper_32_bits(rdev->rlc.save_restore_gpu_addr);
+1
drivers/gpu/drm/radeon/cikd.h
··· 905 905 #define RLC_LB_CNTR_MAX 0xC348 906 906 907 907 #define RLC_LB_CNTL 0xC364 908 + # define LOAD_BALANCE_ENABLE (1 << 0) 908 909 909 910 #define RLC_LB_CNTR_INIT 0xC36C 910 911
+1 -1
drivers/gpu/drm/radeon/si.c
··· 5435 5435 return 0; 5436 5436 } 5437 5437 5438 - static void si_rlc_reset(struct radeon_device *rdev) 5438 + void si_rlc_reset(struct radeon_device *rdev) 5439 5439 { 5440 5440 u32 tmp = RREG32(GRBM_SOFT_RESET); 5441 5441