aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/evergreen.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-02-15 11:02:50 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-06-27 19:16:27 -0400
commitf52382d73e8b5bf8bc9e2faadab365d8c38c64a9 (patch)
tree9141ef08f08c29da296e2b4b6ba8e1628cba3960 /drivers/gpu/drm/radeon/evergreen.c
parent792edd69573da6d8981a82ec830e6257ead822d8 (diff)
drm/radeon: add support for ASPM on evergreen asics
Enables PCIE ASPM (Active State Power Management) on evergreen-cayman asics. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index d0aef76121d5..c6bbf6216498 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -136,6 +136,7 @@ static u32 sumo_rlc_save_restore_register_list_size = ARRAY_SIZE(sumo_rlc_save_r
136static void evergreen_gpu_init(struct radeon_device *rdev); 136static void evergreen_gpu_init(struct radeon_device *rdev);
137void evergreen_fini(struct radeon_device *rdev); 137void evergreen_fini(struct radeon_device *rdev);
138void evergreen_pcie_gen2_enable(struct radeon_device *rdev); 138void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
139void evergreen_program_aspm(struct radeon_device *rdev);
139extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, 140extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
140 int ring, u32 cp_int_cntl); 141 int ring, u32 cp_int_cntl);
141 142
@@ -5071,6 +5072,8 @@ static int evergreen_startup(struct radeon_device *rdev)
5071 5072
5072 /* enable pcie gen2 link */ 5073 /* enable pcie gen2 link */
5073 evergreen_pcie_gen2_enable(rdev); 5074 evergreen_pcie_gen2_enable(rdev);
5075 /* enable aspm */
5076 evergreen_program_aspm(rdev);
5074 5077
5075 if (ASIC_IS_DCE5(rdev)) { 5078 if (ASIC_IS_DCE5(rdev)) {
5076 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { 5079 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
@@ -5468,3 +5471,150 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
5468 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); 5471 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
5469 } 5472 }
5470} 5473}
5474
5475void evergreen_program_aspm(struct radeon_device *rdev)
5476{
5477 u32 data, orig;
5478 u32 pcie_lc_cntl, pcie_lc_cntl_old;
5479 bool disable_l0s, disable_l1 = false, disable_plloff_in_l1 = false;
5480 /* fusion_platform = true
5481 * if the system is a fusion system
5482 * (APU or DGPU in a fusion system).
5483 * todo: check if the system is a fusion platform.
5484 */
5485 bool fusion_platform = false;
5486
5487 if (!(rdev->flags & RADEON_IS_PCIE))
5488 return;
5489
5490 switch (rdev->family) {
5491 case CHIP_CYPRESS:
5492 case CHIP_HEMLOCK:
5493 case CHIP_JUNIPER:
5494 case CHIP_REDWOOD:
5495 case CHIP_CEDAR:
5496 case CHIP_SUMO:
5497 case CHIP_SUMO2:
5498 case CHIP_PALM:
5499 case CHIP_ARUBA:
5500 disable_l0s = true;
5501 break;
5502 default:
5503 disable_l0s = false;
5504 break;
5505 }
5506
5507 if (rdev->flags & RADEON_IS_IGP)
5508 fusion_platform = true; /* XXX also dGPUs in a fusion system */
5509
5510 data = orig = RREG32_PIF_PHY0(PB0_PIF_PAIRING);
5511 if (fusion_platform)
5512 data &= ~MULTI_PIF;
5513 else
5514 data |= MULTI_PIF;
5515 if (data != orig)
5516 WREG32_PIF_PHY0(PB0_PIF_PAIRING, data);
5517
5518 data = orig = RREG32_PIF_PHY1(PB1_PIF_PAIRING);
5519 if (fusion_platform)
5520 data &= ~MULTI_PIF;
5521 else
5522 data |= MULTI_PIF;
5523 if (data != orig)
5524 WREG32_PIF_PHY1(PB1_PIF_PAIRING, data);
5525
5526 pcie_lc_cntl = pcie_lc_cntl_old = RREG32_PCIE_PORT(PCIE_LC_CNTL);
5527 pcie_lc_cntl &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
5528 if (!disable_l0s) {
5529 if (rdev->family >= CHIP_BARTS)
5530 pcie_lc_cntl |= LC_L0S_INACTIVITY(7);
5531 else
5532 pcie_lc_cntl |= LC_L0S_INACTIVITY(3);
5533 }
5534
5535 if (!disable_l1) {
5536 if (rdev->family >= CHIP_BARTS)
5537 pcie_lc_cntl |= LC_L1_INACTIVITY(7);
5538 else
5539 pcie_lc_cntl |= LC_L1_INACTIVITY(8);
5540
5541 if (!disable_plloff_in_l1) {
5542 data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
5543 data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
5544 data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
5545 if (data != orig)
5546 WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
5547
5548 data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
5549 data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
5550 data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
5551 if (data != orig)
5552 WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
5553
5554 data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
5555 data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
5556 data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
5557 if (data != orig)
5558 WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
5559
5560 data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
5561 data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
5562 data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
5563 if (data != orig)
5564 WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
5565
5566 if (rdev->family >= CHIP_BARTS) {
5567 data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
5568 data &= ~PLL_RAMP_UP_TIME_0_MASK;
5569 data |= PLL_RAMP_UP_TIME_0(4);
5570 if (data != orig)
5571 WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
5572
5573 data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
5574 data &= ~PLL_RAMP_UP_TIME_1_MASK;
5575 data |= PLL_RAMP_UP_TIME_1(4);
5576 if (data != orig)
5577 WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
5578
5579 data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
5580 data &= ~PLL_RAMP_UP_TIME_0_MASK;
5581 data |= PLL_RAMP_UP_TIME_0(4);
5582 if (data != orig)
5583 WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
5584
5585 data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
5586 data &= ~PLL_RAMP_UP_TIME_1_MASK;
5587 data |= PLL_RAMP_UP_TIME_1(4);
5588 if (data != orig)
5589 WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
5590 }
5591
5592 data = orig = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
5593 data &= ~LC_DYN_LANES_PWR_STATE_MASK;
5594 data |= LC_DYN_LANES_PWR_STATE(3);
5595 if (data != orig)
5596 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
5597
5598 if (rdev->family >= CHIP_BARTS) {
5599 data = orig = RREG32_PIF_PHY0(PB0_PIF_CNTL);
5600 data &= ~LS2_EXIT_TIME_MASK;
5601 data |= LS2_EXIT_TIME(1);
5602 if (data != orig)
5603 WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
5604
5605 data = orig = RREG32_PIF_PHY1(PB1_PIF_CNTL);
5606 data &= ~LS2_EXIT_TIME_MASK;
5607 data |= LS2_EXIT_TIME(1);
5608 if (data != orig)
5609 WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
5610 }
5611 }
5612 }
5613
5614 /* evergreen parts only */
5615 if (rdev->family < CHIP_BARTS)
5616 pcie_lc_cntl |= LC_PMI_TO_L1_DIS;
5617
5618 if (pcie_lc_cntl != pcie_lc_cntl_old)
5619 WREG32_PCIE_PORT(PCIE_LC_CNTL, pcie_lc_cntl);
5620}