aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/si.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-03-07 12:56:35 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-06-27 19:16:32 -0400
commitf8f84ac5d48c2377131a3c6b8c14e3bdcbf9349e (patch)
tree57d15d110c7113b15fb6295d9d3e381dbadfe366 /drivers/gpu/drm/radeon/si.c
parentbd8cd5391a2e6ca656bb47d65c3c163842679b23 (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.c502
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 */
4558static 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
4575static 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
4601static 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
4622static 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
4635static 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
4651static 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
4660static 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
4673static 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
4684static 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
4709static 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
4729static 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
4752static 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
4785static 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
4823static 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
4877static 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
4909static 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
4922static 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
4940static 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
4955static 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
4965static 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
4985static 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 */
4558void si_rlc_fini(struct radeon_device *rdev) 5002void 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
4718static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, 5162static 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
4744static 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
4761static void si_rlc_stop(struct radeon_device *rdev) 5174static 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);