diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-03-07 12:56:35 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-06-27 19:16:32 -0400 |
commit | f8f84ac5d48c2377131a3c6b8c14e3bdcbf9349e (patch) | |
tree | 57d15d110c7113b15fb6295d9d3e381dbadfe366 /drivers/gpu/drm/radeon/si.c | |
parent | bd8cd5391a2e6ca656bb47d65c3c163842679b23 (diff) |
drm/radeon: implement clock and power gating for SI
Only Cape Verde supports power gating.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/si.c')
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 502 |
1 files changed, 460 insertions, 42 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index ad77dbe1ba7b..6c5cbe0e80b9 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -4553,6 +4553,450 @@ void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
4553 | } | 4553 | } |
4554 | 4554 | ||
4555 | /* | 4555 | /* |
4556 | * Power and clock gating | ||
4557 | */ | ||
4558 | static void si_wait_for_rlc_serdes(struct radeon_device *rdev) | ||
4559 | { | ||
4560 | int i; | ||
4561 | |||
4562 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
4563 | if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0) | ||
4564 | break; | ||
4565 | udelay(1); | ||
4566 | } | ||
4567 | |||
4568 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
4569 | if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0) | ||
4570 | break; | ||
4571 | udelay(1); | ||
4572 | } | ||
4573 | } | ||
4574 | |||
4575 | static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, | ||
4576 | bool enable) | ||
4577 | { | ||
4578 | u32 tmp = RREG32(CP_INT_CNTL_RING0); | ||
4579 | u32 mask; | ||
4580 | int i; | ||
4581 | |||
4582 | if (enable) | ||
4583 | tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | ||
4584 | else | ||
4585 | tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | ||
4586 | WREG32(CP_INT_CNTL_RING0, tmp); | ||
4587 | |||
4588 | if (!enable) { | ||
4589 | /* read a gfx register */ | ||
4590 | tmp = RREG32(DB_DEPTH_INFO); | ||
4591 | |||
4592 | mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS; | ||
4593 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
4594 | if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS)) | ||
4595 | break; | ||
4596 | udelay(1); | ||
4597 | } | ||
4598 | } | ||
4599 | } | ||
4600 | |||
4601 | static void si_set_uvd_dcm(struct radeon_device *rdev, | ||
4602 | bool sw_mode) | ||
4603 | { | ||
4604 | u32 tmp, tmp2; | ||
4605 | |||
4606 | tmp = RREG32(UVD_CGC_CTRL); | ||
4607 | tmp &= ~(CLK_OD_MASK | CG_DT_MASK); | ||
4608 | tmp |= DCM | CG_DT(1) | CLK_OD(4); | ||
4609 | |||
4610 | if (sw_mode) { | ||
4611 | tmp &= ~0x7ffff800; | ||
4612 | tmp2 = DYN_OR_EN | DYN_RR_EN | G_DIV_ID(7); | ||
4613 | } else { | ||
4614 | tmp |= 0x7ffff800; | ||
4615 | tmp2 = 0; | ||
4616 | } | ||
4617 | |||
4618 | WREG32(UVD_CGC_CTRL, tmp); | ||
4619 | WREG32_UVD_CTX(UVD_CGC_CTRL2, tmp2); | ||
4620 | } | ||
4621 | |||
4622 | static void si_init_uvd_internal_cg(struct radeon_device *rdev) | ||
4623 | { | ||
4624 | bool hw_mode = true; | ||
4625 | |||
4626 | if (hw_mode) { | ||
4627 | si_set_uvd_dcm(rdev, false); | ||
4628 | } else { | ||
4629 | u32 tmp = RREG32(UVD_CGC_CTRL); | ||
4630 | tmp &= ~DCM; | ||
4631 | WREG32(UVD_CGC_CTRL, tmp); | ||
4632 | } | ||
4633 | } | ||
4634 | |||
4635 | static u32 si_halt_rlc(struct radeon_device *rdev) | ||
4636 | { | ||
4637 | u32 data, orig; | ||
4638 | |||
4639 | orig = data = RREG32(RLC_CNTL); | ||
4640 | |||
4641 | if (data & RLC_ENABLE) { | ||
4642 | data &= ~RLC_ENABLE; | ||
4643 | WREG32(RLC_CNTL, data); | ||
4644 | |||
4645 | si_wait_for_rlc_serdes(rdev); | ||
4646 | } | ||
4647 | |||
4648 | return orig; | ||
4649 | } | ||
4650 | |||
4651 | static void si_update_rlc(struct radeon_device *rdev, u32 rlc) | ||
4652 | { | ||
4653 | u32 tmp; | ||
4654 | |||
4655 | tmp = RREG32(RLC_CNTL); | ||
4656 | if (tmp != rlc) | ||
4657 | WREG32(RLC_CNTL, rlc); | ||
4658 | } | ||
4659 | |||
4660 | static void si_enable_dma_pg(struct radeon_device *rdev, bool enable) | ||
4661 | { | ||
4662 | u32 data, orig; | ||
4663 | |||
4664 | orig = data = RREG32(DMA_PG); | ||
4665 | if (enable) | ||
4666 | data |= PG_CNTL_ENABLE; | ||
4667 | else | ||
4668 | data &= ~PG_CNTL_ENABLE; | ||
4669 | if (orig != data) | ||
4670 | WREG32(DMA_PG, data); | ||
4671 | } | ||
4672 | |||
4673 | static void si_init_dma_pg(struct radeon_device *rdev) | ||
4674 | { | ||
4675 | u32 tmp; | ||
4676 | |||
4677 | WREG32(DMA_PGFSM_WRITE, 0x00002000); | ||
4678 | WREG32(DMA_PGFSM_CONFIG, 0x100010ff); | ||
4679 | |||
4680 | for (tmp = 0; tmp < 5; tmp++) | ||
4681 | WREG32(DMA_PGFSM_WRITE, 0); | ||
4682 | } | ||
4683 | |||
4684 | static void si_enable_gfx_cgpg(struct radeon_device *rdev, | ||
4685 | bool enable) | ||
4686 | { | ||
4687 | u32 tmp; | ||
4688 | |||
4689 | if (enable) { | ||
4690 | tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10); | ||
4691 | WREG32(RLC_TTOP_D, tmp); | ||
4692 | |||
4693 | tmp = RREG32(RLC_PG_CNTL); | ||
4694 | tmp |= GFX_PG_ENABLE; | ||
4695 | WREG32(RLC_PG_CNTL, tmp); | ||
4696 | |||
4697 | tmp = RREG32(RLC_AUTO_PG_CTRL); | ||
4698 | tmp |= AUTO_PG_EN; | ||
4699 | WREG32(RLC_AUTO_PG_CTRL, tmp); | ||
4700 | } else { | ||
4701 | tmp = RREG32(RLC_AUTO_PG_CTRL); | ||
4702 | tmp &= ~AUTO_PG_EN; | ||
4703 | WREG32(RLC_AUTO_PG_CTRL, tmp); | ||
4704 | |||
4705 | tmp = RREG32(DB_RENDER_CONTROL); | ||
4706 | } | ||
4707 | } | ||
4708 | |||
4709 | static void si_init_gfx_cgpg(struct radeon_device *rdev) | ||
4710 | { | ||
4711 | u32 tmp; | ||
4712 | |||
4713 | WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); | ||
4714 | |||
4715 | tmp = RREG32(RLC_PG_CNTL); | ||
4716 | tmp |= GFX_PG_SRC; | ||
4717 | WREG32(RLC_PG_CNTL, tmp); | ||
4718 | |||
4719 | WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); | ||
4720 | |||
4721 | tmp = RREG32(RLC_AUTO_PG_CTRL); | ||
4722 | |||
4723 | tmp &= ~GRBM_REG_SGIT_MASK; | ||
4724 | tmp |= GRBM_REG_SGIT(0x700); | ||
4725 | tmp &= ~PG_AFTER_GRBM_REG_ST_MASK; | ||
4726 | WREG32(RLC_AUTO_PG_CTRL, tmp); | ||
4727 | } | ||
4728 | |||
4729 | static u32 get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh) | ||
4730 | { | ||
4731 | u32 mask = 0, tmp, tmp1; | ||
4732 | int i; | ||
4733 | |||
4734 | si_select_se_sh(rdev, se, sh); | ||
4735 | tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG); | ||
4736 | tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG); | ||
4737 | si_select_se_sh(rdev, 0xffffffff, 0xffffffff); | ||
4738 | |||
4739 | tmp &= 0xffff0000; | ||
4740 | |||
4741 | tmp |= tmp1; | ||
4742 | tmp >>= 16; | ||
4743 | |||
4744 | for (i = 0; i < rdev->config.si.max_cu_per_sh; i ++) { | ||
4745 | mask <<= 1; | ||
4746 | mask |= 1; | ||
4747 | } | ||
4748 | |||
4749 | return (~tmp) & mask; | ||
4750 | } | ||
4751 | |||
4752 | static void si_init_ao_cu_mask(struct radeon_device *rdev) | ||
4753 | { | ||
4754 | u32 i, j, k, active_cu_number = 0; | ||
4755 | u32 mask, counter, cu_bitmap; | ||
4756 | u32 tmp = 0; | ||
4757 | |||
4758 | for (i = 0; i < rdev->config.si.max_shader_engines; i++) { | ||
4759 | for (j = 0; j < rdev->config.si.max_sh_per_se; j++) { | ||
4760 | mask = 1; | ||
4761 | cu_bitmap = 0; | ||
4762 | counter = 0; | ||
4763 | for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) { | ||
4764 | if (get_cu_active_bitmap(rdev, i, j) & mask) { | ||
4765 | if (counter < 2) | ||
4766 | cu_bitmap |= mask; | ||
4767 | counter++; | ||
4768 | } | ||
4769 | mask <<= 1; | ||
4770 | } | ||
4771 | |||
4772 | active_cu_number += counter; | ||
4773 | tmp |= (cu_bitmap << (i * 16 + j * 8)); | ||
4774 | } | ||
4775 | } | ||
4776 | |||
4777 | WREG32(RLC_PG_AO_CU_MASK, tmp); | ||
4778 | |||
4779 | tmp = RREG32(RLC_MAX_PG_CU); | ||
4780 | tmp &= ~MAX_PU_CU_MASK; | ||
4781 | tmp |= MAX_PU_CU(active_cu_number); | ||
4782 | WREG32(RLC_MAX_PG_CU, tmp); | ||
4783 | } | ||
4784 | |||
4785 | static void si_enable_cgcg(struct radeon_device *rdev, | ||
4786 | bool enable) | ||
4787 | { | ||
4788 | u32 data, orig, tmp; | ||
4789 | |||
4790 | orig = data = RREG32(RLC_CGCG_CGLS_CTRL); | ||
4791 | |||
4792 | si_enable_gui_idle_interrupt(rdev, enable); | ||
4793 | |||
4794 | if (enable) { | ||
4795 | WREG32(RLC_GCPM_GENERAL_3, 0x00000080); | ||
4796 | |||
4797 | tmp = si_halt_rlc(rdev); | ||
4798 | |||
4799 | WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff); | ||
4800 | WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff); | ||
4801 | WREG32(RLC_SERDES_WR_CTRL, 0x00b000ff); | ||
4802 | |||
4803 | si_wait_for_rlc_serdes(rdev); | ||
4804 | |||
4805 | si_update_rlc(rdev, tmp); | ||
4806 | |||
4807 | WREG32(RLC_SERDES_WR_CTRL, 0x007000ff); | ||
4808 | |||
4809 | data |= CGCG_EN | CGLS_EN; | ||
4810 | } else { | ||
4811 | RREG32(CB_CGTT_SCLK_CTRL); | ||
4812 | RREG32(CB_CGTT_SCLK_CTRL); | ||
4813 | RREG32(CB_CGTT_SCLK_CTRL); | ||
4814 | RREG32(CB_CGTT_SCLK_CTRL); | ||
4815 | |||
4816 | data &= ~(CGCG_EN | CGLS_EN); | ||
4817 | } | ||
4818 | |||
4819 | if (orig != data) | ||
4820 | WREG32(RLC_CGCG_CGLS_CTRL, data); | ||
4821 | } | ||
4822 | |||
4823 | static void si_enable_mgcg(struct radeon_device *rdev, | ||
4824 | bool enable) | ||
4825 | { | ||
4826 | u32 data, orig, tmp = 0; | ||
4827 | |||
4828 | if (enable) { | ||
4829 | orig = data = RREG32(CGTS_SM_CTRL_REG); | ||
4830 | data = 0x96940200; | ||
4831 | if (orig != data) | ||
4832 | WREG32(CGTS_SM_CTRL_REG, data); | ||
4833 | |||
4834 | orig = data = RREG32(CP_MEM_SLP_CNTL); | ||
4835 | data |= CP_MEM_LS_EN; | ||
4836 | if (orig != data) | ||
4837 | WREG32(CP_MEM_SLP_CNTL, data); | ||
4838 | |||
4839 | orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); | ||
4840 | data &= 0xffffffc0; | ||
4841 | if (orig != data) | ||
4842 | WREG32(RLC_CGTT_MGCG_OVERRIDE, data); | ||
4843 | |||
4844 | tmp = si_halt_rlc(rdev); | ||
4845 | |||
4846 | WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff); | ||
4847 | WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff); | ||
4848 | WREG32(RLC_SERDES_WR_CTRL, 0x00d000ff); | ||
4849 | |||
4850 | si_update_rlc(rdev, tmp); | ||
4851 | } else { | ||
4852 | orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); | ||
4853 | data |= 0x00000003; | ||
4854 | if (orig != data) | ||
4855 | WREG32(RLC_CGTT_MGCG_OVERRIDE, data); | ||
4856 | |||
4857 | data = RREG32(CP_MEM_SLP_CNTL); | ||
4858 | if (data & CP_MEM_LS_EN) { | ||
4859 | data &= ~CP_MEM_LS_EN; | ||
4860 | WREG32(CP_MEM_SLP_CNTL, data); | ||
4861 | } | ||
4862 | orig = data = RREG32(CGTS_SM_CTRL_REG); | ||
4863 | data |= LS_OVERRIDE | OVERRIDE; | ||
4864 | if (orig != data) | ||
4865 | WREG32(CGTS_SM_CTRL_REG, data); | ||
4866 | |||
4867 | tmp = si_halt_rlc(rdev); | ||
4868 | |||
4869 | WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff); | ||
4870 | WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff); | ||
4871 | WREG32(RLC_SERDES_WR_CTRL, 0x00e000ff); | ||
4872 | |||
4873 | si_update_rlc(rdev, tmp); | ||
4874 | } | ||
4875 | } | ||
4876 | |||
4877 | static void si_enable_uvd_mgcg(struct radeon_device *rdev, | ||
4878 | bool enable) | ||
4879 | { | ||
4880 | u32 orig, data, tmp; | ||
4881 | |||
4882 | if (enable) { | ||
4883 | tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL); | ||
4884 | tmp |= 0x3fff; | ||
4885 | WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp); | ||
4886 | |||
4887 | orig = data = RREG32(UVD_CGC_CTRL); | ||
4888 | data |= DCM; | ||
4889 | if (orig != data) | ||
4890 | WREG32(UVD_CGC_CTRL, data); | ||
4891 | |||
4892 | WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0); | ||
4893 | WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0); | ||
4894 | } else { | ||
4895 | tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL); | ||
4896 | tmp &= ~0x3fff; | ||
4897 | WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp); | ||
4898 | |||
4899 | orig = data = RREG32(UVD_CGC_CTRL); | ||
4900 | data &= ~DCM; | ||
4901 | if (orig != data) | ||
4902 | WREG32(UVD_CGC_CTRL, data); | ||
4903 | |||
4904 | WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0xffffffff); | ||
4905 | WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0xffffffff); | ||
4906 | } | ||
4907 | } | ||
4908 | |||
4909 | static const u32 mc_cg_registers[] = | ||
4910 | { | ||
4911 | MC_HUB_MISC_HUB_CG, | ||
4912 | MC_HUB_MISC_SIP_CG, | ||
4913 | MC_HUB_MISC_VM_CG, | ||
4914 | MC_XPB_CLK_GAT, | ||
4915 | ATC_MISC_CG, | ||
4916 | MC_CITF_MISC_WR_CG, | ||
4917 | MC_CITF_MISC_RD_CG, | ||
4918 | MC_CITF_MISC_VM_CG, | ||
4919 | VM_L2_CG, | ||
4920 | }; | ||
4921 | |||
4922 | static void si_enable_mc_ls(struct radeon_device *rdev, | ||
4923 | bool enable) | ||
4924 | { | ||
4925 | int i; | ||
4926 | u32 orig, data; | ||
4927 | |||
4928 | for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) { | ||
4929 | orig = data = RREG32(mc_cg_registers[i]); | ||
4930 | if (enable) | ||
4931 | data |= MC_LS_ENABLE; | ||
4932 | else | ||
4933 | data &= ~MC_LS_ENABLE; | ||
4934 | if (data != orig) | ||
4935 | WREG32(mc_cg_registers[i], data); | ||
4936 | } | ||
4937 | } | ||
4938 | |||
4939 | |||
4940 | static void si_init_cg(struct radeon_device *rdev) | ||
4941 | { | ||
4942 | bool has_uvd = true; | ||
4943 | |||
4944 | si_enable_mgcg(rdev, true); | ||
4945 | si_enable_cgcg(rdev, true); | ||
4946 | /* disable MC LS on Tahiti */ | ||
4947 | if (rdev->family == CHIP_TAHITI) | ||
4948 | si_enable_mc_ls(rdev, false); | ||
4949 | if (has_uvd) { | ||
4950 | si_enable_uvd_mgcg(rdev, true); | ||
4951 | si_init_uvd_internal_cg(rdev); | ||
4952 | } | ||
4953 | } | ||
4954 | |||
4955 | static void si_fini_cg(struct radeon_device *rdev) | ||
4956 | { | ||
4957 | bool has_uvd = true; | ||
4958 | |||
4959 | if (has_uvd) | ||
4960 | si_enable_uvd_mgcg(rdev, false); | ||
4961 | si_enable_cgcg(rdev, false); | ||
4962 | si_enable_mgcg(rdev, false); | ||
4963 | } | ||
4964 | |||
4965 | static void si_init_pg(struct radeon_device *rdev) | ||
4966 | { | ||
4967 | bool has_pg = false; | ||
4968 | |||
4969 | /* only cape verde supports PG */ | ||
4970 | if (rdev->family == CHIP_VERDE) | ||
4971 | has_pg = true; | ||
4972 | |||
4973 | if (has_pg) { | ||
4974 | si_init_ao_cu_mask(rdev); | ||
4975 | si_init_dma_pg(rdev); | ||
4976 | si_enable_dma_pg(rdev, true); | ||
4977 | si_init_gfx_cgpg(rdev); | ||
4978 | si_enable_gfx_cgpg(rdev, true); | ||
4979 | } else { | ||
4980 | WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); | ||
4981 | WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); | ||
4982 | } | ||
4983 | } | ||
4984 | |||
4985 | static void si_fini_pg(struct radeon_device *rdev) | ||
4986 | { | ||
4987 | bool has_pg = false; | ||
4988 | |||
4989 | /* only cape verde supports PG */ | ||
4990 | if (rdev->family == CHIP_VERDE) | ||
4991 | has_pg = true; | ||
4992 | |||
4993 | if (has_pg) { | ||
4994 | si_enable_dma_pg(rdev, false); | ||
4995 | si_enable_gfx_cgpg(rdev, false); | ||
4996 | } | ||
4997 | } | ||
4998 | |||
4999 | /* | ||
4556 | * RLC | 5000 | * RLC |
4557 | */ | 5001 | */ |
4558 | void si_rlc_fini(struct radeon_device *rdev) | 5002 | void si_rlc_fini(struct radeon_device *rdev) |
@@ -4715,47 +5159,16 @@ int si_rlc_init(struct radeon_device *rdev) | |||
4715 | return 0; | 5159 | return 0; |
4716 | } | 5160 | } |
4717 | 5161 | ||
4718 | static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, | 5162 | static void si_rlc_reset(struct radeon_device *rdev) |
4719 | bool enable) | ||
4720 | { | 5163 | { |
4721 | u32 tmp = RREG32(CP_INT_CNTL_RING0); | 5164 | u32 tmp = RREG32(GRBM_SOFT_RESET); |
4722 | u32 mask; | ||
4723 | int i; | ||
4724 | |||
4725 | if (enable) | ||
4726 | tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | ||
4727 | else | ||
4728 | tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | ||
4729 | WREG32(CP_INT_CNTL_RING0, tmp); | ||
4730 | |||
4731 | if (!enable) { | ||
4732 | /* read a gfx register */ | ||
4733 | tmp = RREG32(DB_DEPTH_INFO); | ||
4734 | 5165 | ||
4735 | mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS; | 5166 | tmp |= SOFT_RESET_RLC; |
4736 | for (i = 0; i < rdev->usec_timeout; i++) { | 5167 | WREG32(GRBM_SOFT_RESET, tmp); |
4737 | if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS)) | 5168 | udelay(50); |
4738 | break; | 5169 | tmp &= ~SOFT_RESET_RLC; |
4739 | udelay(1); | 5170 | WREG32(GRBM_SOFT_RESET, tmp); |
4740 | } | 5171 | udelay(50); |
4741 | } | ||
4742 | } | ||
4743 | |||
4744 | static void si_wait_for_rlc_serdes(struct radeon_device *rdev) | ||
4745 | { | ||
4746 | int i; | ||
4747 | |||
4748 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
4749 | if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0) | ||
4750 | break; | ||
4751 | udelay(1); | ||
4752 | } | ||
4753 | |||
4754 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
4755 | if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0) | ||
4756 | break; | ||
4757 | udelay(1); | ||
4758 | } | ||
4759 | } | 5172 | } |
4760 | 5173 | ||
4761 | static void si_rlc_stop(struct radeon_device *rdev) | 5174 | static void si_rlc_stop(struct radeon_device *rdev) |
@@ -4814,6 +5227,12 @@ static int si_rlc_resume(struct radeon_device *rdev) | |||
4814 | 5227 | ||
4815 | si_rlc_stop(rdev); | 5228 | si_rlc_stop(rdev); |
4816 | 5229 | ||
5230 | si_rlc_reset(rdev); | ||
5231 | |||
5232 | si_init_pg(rdev); | ||
5233 | |||
5234 | si_init_cg(rdev); | ||
5235 | |||
4817 | WREG32(RLC_RL_BASE, 0); | 5236 | WREG32(RLC_RL_BASE, 0); |
4818 | WREG32(RLC_RL_SIZE, 0); | 5237 | WREG32(RLC_RL_SIZE, 0); |
4819 | WREG32(RLC_LB_CNTL, 0); | 5238 | WREG32(RLC_LB_CNTL, 0); |
@@ -4821,9 +5240,6 @@ static int si_rlc_resume(struct radeon_device *rdev) | |||
4821 | WREG32(RLC_LB_CNTR_INIT, 0); | 5240 | WREG32(RLC_LB_CNTR_INIT, 0); |
4822 | WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff); | 5241 | WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff); |
4823 | 5242 | ||
4824 | WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); | ||
4825 | WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); | ||
4826 | |||
4827 | WREG32(RLC_MC_CNTL, 0); | 5243 | WREG32(RLC_MC_CNTL, 0); |
4828 | WREG32(RLC_UCODE_CNTL, 0); | 5244 | WREG32(RLC_UCODE_CNTL, 0); |
4829 | 5245 | ||
@@ -6041,6 +6457,8 @@ void si_fini(struct radeon_device *rdev) | |||
6041 | cayman_dma_fini(rdev); | 6457 | cayman_dma_fini(rdev); |
6042 | si_irq_fini(rdev); | 6458 | si_irq_fini(rdev); |
6043 | si_rlc_fini(rdev); | 6459 | si_rlc_fini(rdev); |
6460 | si_fini_cg(rdev); | ||
6461 | si_fini_pg(rdev); | ||
6044 | radeon_wb_fini(rdev); | 6462 | radeon_wb_fini(rdev); |
6045 | radeon_vm_manager_fini(rdev); | 6463 | radeon_vm_manager_fini(rdev); |
6046 | radeon_ib_pool_fini(rdev); | 6464 | radeon_ib_pool_fini(rdev); |