diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2011-01-06 18:49:35 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-01-06 23:11:14 -0500 |
commit | 9e46a48df24f9698b34d28385b320c529851e5f7 (patch) | |
tree | 9b89b4f1240fcb02e114704d93fb8b98febed85a /drivers/gpu/drm/radeon/r600.c | |
parent | 3313e3d4333ccbf8bd7c816775cfe9aca623bd8a (diff) |
drm/radeon/kms: add support for gen2 pcie link speeds
Supported on rv6xx/r7xx/evergreen. Cards come up in gen1 mode.
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 60ad8c03081a..6b50716267c0 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -94,6 +94,7 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); | |||
94 | void r600_gpu_init(struct radeon_device *rdev); | 94 | void r600_gpu_init(struct radeon_device *rdev); |
95 | void r600_fini(struct radeon_device *rdev); | 95 | void r600_fini(struct radeon_device *rdev); |
96 | void r600_irq_disable(struct radeon_device *rdev); | 96 | void r600_irq_disable(struct radeon_device *rdev); |
97 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); | ||
97 | 98 | ||
98 | /* get temperature in millidegrees */ | 99 | /* get temperature in millidegrees */ |
99 | u32 rv6xx_get_temp(struct radeon_device *rdev) | 100 | u32 rv6xx_get_temp(struct radeon_device *rdev) |
@@ -2379,6 +2380,9 @@ int r600_startup(struct radeon_device *rdev) | |||
2379 | { | 2380 | { |
2380 | int r; | 2381 | int r; |
2381 | 2382 | ||
2383 | /* enable pcie gen2 link */ | ||
2384 | r600_pcie_gen2_enable(rdev); | ||
2385 | |||
2382 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 2386 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
2383 | r = r600_init_microcode(rdev); | 2387 | r = r600_init_microcode(rdev); |
2384 | if (r) { | 2388 | if (r) { |
@@ -3649,3 +3653,101 @@ int r600_get_pcie_lanes(struct radeon_device *rdev) | |||
3649 | } | 3653 | } |
3650 | } | 3654 | } |
3651 | 3655 | ||
3656 | static void r600_pcie_gen2_enable(struct radeon_device *rdev) | ||
3657 | { | ||
3658 | u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp; | ||
3659 | u16 link_cntl2; | ||
3660 | |||
3661 | if (rdev->flags & RADEON_IS_IGP) | ||
3662 | return; | ||
3663 | |||
3664 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3665 | return; | ||
3666 | |||
3667 | /* x2 cards have a special sequence */ | ||
3668 | if (ASIC_IS_X2(rdev)) | ||
3669 | return; | ||
3670 | |||
3671 | /* only RV6xx+ chips are supported */ | ||
3672 | if (rdev->family <= CHIP_R600) | ||
3673 | return; | ||
3674 | |||
3675 | /* 55 nm r6xx asics */ | ||
3676 | if ((rdev->family == CHIP_RV670) || | ||
3677 | (rdev->family == CHIP_RV620) || | ||
3678 | (rdev->family == CHIP_RV635)) { | ||
3679 | /* advertise upconfig capability */ | ||
3680 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3681 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3682 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3683 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3684 | if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { | ||
3685 | lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; | ||
3686 | link_width_cntl &= ~(LC_LINK_WIDTH_MASK | | ||
3687 | LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
3688 | link_width_cntl |= lanes | LC_RECONFIG_NOW | LC_RENEGOTIATE_EN; | ||
3689 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3690 | } else { | ||
3691 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
3692 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3693 | } | ||
3694 | } | ||
3695 | |||
3696 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3697 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
3698 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
3699 | |||
3700 | /* 55 nm r6xx asics */ | ||
3701 | if ((rdev->family == CHIP_RV670) || | ||
3702 | (rdev->family == CHIP_RV620) || | ||
3703 | (rdev->family == CHIP_RV635)) { | ||
3704 | WREG32(MM_CFGREGS_CNTL, 0x8); | ||
3705 | link_cntl2 = RREG32(0x4088); | ||
3706 | WREG32(MM_CFGREGS_CNTL, 0); | ||
3707 | /* not supported yet */ | ||
3708 | if (link_cntl2 & SELECTABLE_DEEMPHASIS) | ||
3709 | return; | ||
3710 | } | ||
3711 | |||
3712 | speed_cntl &= ~LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK; | ||
3713 | speed_cntl |= (0x3 << LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT); | ||
3714 | speed_cntl &= ~LC_VOLTAGE_TIMER_SEL_MASK; | ||
3715 | speed_cntl &= ~LC_FORCE_DIS_HW_SPEED_CHANGE; | ||
3716 | speed_cntl |= LC_FORCE_EN_HW_SPEED_CHANGE; | ||
3717 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3718 | |||
3719 | tmp = RREG32(0x541c); | ||
3720 | WREG32(0x541c, tmp | 0x8); | ||
3721 | WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); | ||
3722 | link_cntl2 = RREG16(0x4088); | ||
3723 | link_cntl2 &= ~TARGET_LINK_SPEED_MASK; | ||
3724 | link_cntl2 |= 0x2; | ||
3725 | WREG16(0x4088, link_cntl2); | ||
3726 | WREG32(MM_CFGREGS_CNTL, 0); | ||
3727 | |||
3728 | if ((rdev->family == CHIP_RV670) || | ||
3729 | (rdev->family == CHIP_RV620) || | ||
3730 | (rdev->family == CHIP_RV635)) { | ||
3731 | training_cntl = RREG32_PCIE_P(PCIE_LC_TRAINING_CNTL); | ||
3732 | training_cntl &= ~LC_POINT_7_PLUS_EN; | ||
3733 | WREG32_PCIE_P(PCIE_LC_TRAINING_CNTL, training_cntl); | ||
3734 | } else { | ||
3735 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3736 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
3737 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3738 | } | ||
3739 | |||
3740 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3741 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
3742 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3743 | |||
3744 | } else { | ||
3745 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3746 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
3747 | if (1) | ||
3748 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
3749 | else | ||
3750 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3751 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3752 | } | ||
3753 | } | ||