diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-02-15 11:02:50 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-06-27 19:16:27 -0400 |
commit | f52382d73e8b5bf8bc9e2faadab365d8c38c64a9 (patch) | |
tree | 9141ef08f08c29da296e2b4b6ba8e1628cba3960 /drivers/gpu/drm/radeon/evergreen.c | |
parent | 792edd69573da6d8981a82ec830e6257ead822d8 (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.c | 150 |
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 | |||
136 | static void evergreen_gpu_init(struct radeon_device *rdev); | 136 | static void evergreen_gpu_init(struct radeon_device *rdev); |
137 | void evergreen_fini(struct radeon_device *rdev); | 137 | void evergreen_fini(struct radeon_device *rdev); |
138 | void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | 138 | void evergreen_pcie_gen2_enable(struct radeon_device *rdev); |
139 | void evergreen_program_aspm(struct radeon_device *rdev); | ||
139 | extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, | 140 | extern 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 | |||
5475 | void 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 | } | ||