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 | |
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')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 38 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 102 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600d.h | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 76 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770d.h | 38 |
7 files changed, 348 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index eaf4fba90b72..11344c76e216 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -39,6 +39,7 @@ | |||
39 | 39 | ||
40 | static void evergreen_gpu_init(struct radeon_device *rdev); | 40 | static void evergreen_gpu_init(struct radeon_device *rdev); |
41 | void evergreen_fini(struct radeon_device *rdev); | 41 | void evergreen_fini(struct radeon_device *rdev); |
42 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | ||
42 | 43 | ||
43 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) | 44 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) |
44 | { | 45 | { |
@@ -2767,6 +2768,9 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
2767 | { | 2768 | { |
2768 | int r; | 2769 | int r; |
2769 | 2770 | ||
2771 | /* enable pcie gen2 link */ | ||
2772 | evergreen_pcie_gen2_enable(rdev); | ||
2773 | |||
2770 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 2774 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
2771 | r = r600_init_microcode(rdev); | 2775 | r = r600_init_microcode(rdev); |
2772 | if (r) { | 2776 | if (r) { |
@@ -3049,3 +3053,52 @@ void evergreen_fini(struct radeon_device *rdev) | |||
3049 | rdev->bios = NULL; | 3053 | rdev->bios = NULL; |
3050 | radeon_dummy_page_fini(rdev); | 3054 | radeon_dummy_page_fini(rdev); |
3051 | } | 3055 | } |
3056 | |||
3057 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev) | ||
3058 | { | ||
3059 | u32 link_width_cntl, speed_cntl; | ||
3060 | |||
3061 | if (rdev->flags & RADEON_IS_IGP) | ||
3062 | return; | ||
3063 | |||
3064 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3065 | return; | ||
3066 | |||
3067 | /* x2 cards have a special sequence */ | ||
3068 | if (ASIC_IS_X2(rdev)) | ||
3069 | return; | ||
3070 | |||
3071 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3072 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || | ||
3073 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
3074 | |||
3075 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3076 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3077 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3078 | |||
3079 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3080 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
3081 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3082 | |||
3083 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3084 | speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
3085 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3086 | |||
3087 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3088 | speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
3089 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3090 | |||
3091 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3092 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
3093 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3094 | |||
3095 | } else { | ||
3096 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3097 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
3098 | if (1) | ||
3099 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
3100 | else | ||
3101 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3102 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3103 | } | ||
3104 | } | ||
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 94140e142abb..b8da323f15c8 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -581,6 +581,44 @@ | |||
581 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) | 581 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) |
582 | # define DC_HPDx_EN (1 << 28) | 582 | # define DC_HPDx_EN (1 << 28) |
583 | 583 | ||
584 | /* PCIE link stuff */ | ||
585 | #define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ | ||
586 | #define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ | ||
587 | # define LC_LINK_WIDTH_SHIFT 0 | ||
588 | # define LC_LINK_WIDTH_MASK 0x7 | ||
589 | # define LC_LINK_WIDTH_X0 0 | ||
590 | # define LC_LINK_WIDTH_X1 1 | ||
591 | # define LC_LINK_WIDTH_X2 2 | ||
592 | # define LC_LINK_WIDTH_X4 3 | ||
593 | # define LC_LINK_WIDTH_X8 4 | ||
594 | # define LC_LINK_WIDTH_X16 6 | ||
595 | # define LC_LINK_WIDTH_RD_SHIFT 4 | ||
596 | # define LC_LINK_WIDTH_RD_MASK 0x70 | ||
597 | # define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) | ||
598 | # define LC_RECONFIG_NOW (1 << 8) | ||
599 | # define LC_RENEGOTIATION_SUPPORT (1 << 9) | ||
600 | # define LC_RENEGOTIATE_EN (1 << 10) | ||
601 | # define LC_SHORT_RECONFIG_EN (1 << 11) | ||
602 | # define LC_UPCONFIGURE_SUPPORT (1 << 12) | ||
603 | # define LC_UPCONFIGURE_DIS (1 << 13) | ||
604 | #define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ | ||
605 | # define LC_GEN2_EN_STRAP (1 << 0) | ||
606 | # define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) | ||
607 | # define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) | ||
608 | # define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) | ||
609 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) | ||
610 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 | ||
611 | # define LC_CURRENT_DATA_RATE (1 << 11) | ||
612 | # define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) | ||
613 | # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) | ||
614 | # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) | ||
615 | # define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) | ||
616 | #define MM_CFGREGS_CNTL 0x544c | ||
617 | # define MM_WR_TO_CFG_EN (1 << 3) | ||
618 | #define LINK_CNTL2 0x88 /* F0 */ | ||
619 | # define TARGET_LINK_SPEED_MASK (0xf << 0) | ||
620 | # define SELECTABLE_DEEMPHASIS (1 << 6) | ||
621 | |||
584 | /* | 622 | /* |
585 | * PM4 | 623 | * PM4 |
586 | */ | 624 | */ |
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 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index c89cfa8e0c05..a5d898b4bad2 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -737,6 +737,45 @@ | |||
737 | # define DxGRPH_PFLIP_INT_MASK (1 << 0) | 737 | # define DxGRPH_PFLIP_INT_MASK (1 << 0) |
738 | # define DxGRPH_PFLIP_INT_TYPE (1 << 8) | 738 | # define DxGRPH_PFLIP_INT_TYPE (1 << 8) |
739 | 739 | ||
740 | /* PCIE link stuff */ | ||
741 | #define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ | ||
742 | # define LC_POINT_7_PLUS_EN (1 << 6) | ||
743 | #define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ | ||
744 | # define LC_LINK_WIDTH_SHIFT 0 | ||
745 | # define LC_LINK_WIDTH_MASK 0x7 | ||
746 | # define LC_LINK_WIDTH_X0 0 | ||
747 | # define LC_LINK_WIDTH_X1 1 | ||
748 | # define LC_LINK_WIDTH_X2 2 | ||
749 | # define LC_LINK_WIDTH_X4 3 | ||
750 | # define LC_LINK_WIDTH_X8 4 | ||
751 | # define LC_LINK_WIDTH_X16 6 | ||
752 | # define LC_LINK_WIDTH_RD_SHIFT 4 | ||
753 | # define LC_LINK_WIDTH_RD_MASK 0x70 | ||
754 | # define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) | ||
755 | # define LC_RECONFIG_NOW (1 << 8) | ||
756 | # define LC_RENEGOTIATION_SUPPORT (1 << 9) | ||
757 | # define LC_RENEGOTIATE_EN (1 << 10) | ||
758 | # define LC_SHORT_RECONFIG_EN (1 << 11) | ||
759 | # define LC_UPCONFIGURE_SUPPORT (1 << 12) | ||
760 | # define LC_UPCONFIGURE_DIS (1 << 13) | ||
761 | #define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ | ||
762 | # define LC_GEN2_EN_STRAP (1 << 0) | ||
763 | # define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) | ||
764 | # define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) | ||
765 | # define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) | ||
766 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) | ||
767 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 | ||
768 | # define LC_CURRENT_DATA_RATE (1 << 11) | ||
769 | # define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) | ||
770 | # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) | ||
771 | # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) | ||
772 | # define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) | ||
773 | #define MM_CFGREGS_CNTL 0x544c | ||
774 | # define MM_WR_TO_CFG_EN (1 << 3) | ||
775 | #define LINK_CNTL2 0x88 /* F0 */ | ||
776 | # define TARGET_LINK_SPEED_MASK (0xf << 0) | ||
777 | # define SELECTABLE_DEEMPHASIS (1 << 6) | ||
778 | |||
740 | /* | 779 | /* |
741 | * PM4 | 780 | * PM4 |
742 | */ | 781 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e9fb64c1e20b..3e635c651900 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1244,6 +1244,8 @@ static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
1244 | */ | 1244 | */ |
1245 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) | 1245 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) |
1246 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) | 1246 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) |
1247 | #define RREG16(reg) readw(((void __iomem *)rdev->rmmio) + (reg)) | ||
1248 | #define WREG16(reg, v) writew(v, ((void __iomem *)rdev->rmmio) + (reg)) | ||
1247 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) | 1249 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) |
1248 | #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) | 1250 | #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) |
1249 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) | 1251 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 645aa1fd7611..3a264aa3a79a 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | static void rv770_gpu_init(struct radeon_device *rdev); | 42 | static void rv770_gpu_init(struct radeon_device *rdev); |
43 | void rv770_fini(struct radeon_device *rdev); | 43 | void rv770_fini(struct radeon_device *rdev); |
44 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev); | ||
44 | 45 | ||
45 | u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | 46 | u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) |
46 | { | 47 | { |
@@ -1124,6 +1125,9 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1124 | { | 1125 | { |
1125 | int r; | 1126 | int r; |
1126 | 1127 | ||
1128 | /* enable pcie gen2 link */ | ||
1129 | rv770_pcie_gen2_enable(rdev); | ||
1130 | |||
1127 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 1131 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
1128 | r = r600_init_microcode(rdev); | 1132 | r = r600_init_microcode(rdev); |
1129 | if (r) { | 1133 | if (r) { |
@@ -1362,3 +1366,75 @@ void rv770_fini(struct radeon_device *rdev) | |||
1362 | rdev->bios = NULL; | 1366 | rdev->bios = NULL; |
1363 | radeon_dummy_page_fini(rdev); | 1367 | radeon_dummy_page_fini(rdev); |
1364 | } | 1368 | } |
1369 | |||
1370 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev) | ||
1371 | { | ||
1372 | u32 link_width_cntl, lanes, speed_cntl, tmp; | ||
1373 | u16 link_cntl2; | ||
1374 | |||
1375 | if (rdev->flags & RADEON_IS_IGP) | ||
1376 | return; | ||
1377 | |||
1378 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
1379 | return; | ||
1380 | |||
1381 | /* x2 cards have a special sequence */ | ||
1382 | if (ASIC_IS_X2(rdev)) | ||
1383 | return; | ||
1384 | |||
1385 | /* advertise upconfig capability */ | ||
1386 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
1387 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
1388 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
1389 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
1390 | if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { | ||
1391 | lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; | ||
1392 | link_width_cntl &= ~(LC_LINK_WIDTH_MASK | | ||
1393 | LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
1394 | link_width_cntl |= lanes | LC_RECONFIG_NOW | | ||
1395 | LC_RENEGOTIATE_EN | LC_UPCONFIGURE_SUPPORT; | ||
1396 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
1397 | } else { | ||
1398 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
1399 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
1400 | } | ||
1401 | |||
1402 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1403 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
1404 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
1405 | |||
1406 | tmp = RREG32(0x541c); | ||
1407 | WREG32(0x541c, tmp | 0x8); | ||
1408 | WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); | ||
1409 | link_cntl2 = RREG16(0x4088); | ||
1410 | link_cntl2 &= ~TARGET_LINK_SPEED_MASK; | ||
1411 | link_cntl2 |= 0x2; | ||
1412 | WREG16(0x4088, link_cntl2); | ||
1413 | WREG32(MM_CFGREGS_CNTL, 0); | ||
1414 | |||
1415 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1416 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
1417 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
1418 | |||
1419 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1420 | speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
1421 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
1422 | |||
1423 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1424 | speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
1425 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
1426 | |||
1427 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1428 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
1429 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
1430 | |||
1431 | } else { | ||
1432 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
1433 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
1434 | if (1) | ||
1435 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
1436 | else | ||
1437 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
1438 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
1439 | } | ||
1440 | } | ||
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index fc77e1e1a179..abc8cf5a3672 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
@@ -360,4 +360,42 @@ | |||
360 | #define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c | 360 | #define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c |
361 | #define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c | 361 | #define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c |
362 | 362 | ||
363 | /* PCIE link stuff */ | ||
364 | #define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ | ||
365 | #define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ | ||
366 | # define LC_LINK_WIDTH_SHIFT 0 | ||
367 | # define LC_LINK_WIDTH_MASK 0x7 | ||
368 | # define LC_LINK_WIDTH_X0 0 | ||
369 | # define LC_LINK_WIDTH_X1 1 | ||
370 | # define LC_LINK_WIDTH_X2 2 | ||
371 | # define LC_LINK_WIDTH_X4 3 | ||
372 | # define LC_LINK_WIDTH_X8 4 | ||
373 | # define LC_LINK_WIDTH_X16 6 | ||
374 | # define LC_LINK_WIDTH_RD_SHIFT 4 | ||
375 | # define LC_LINK_WIDTH_RD_MASK 0x70 | ||
376 | # define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) | ||
377 | # define LC_RECONFIG_NOW (1 << 8) | ||
378 | # define LC_RENEGOTIATION_SUPPORT (1 << 9) | ||
379 | # define LC_RENEGOTIATE_EN (1 << 10) | ||
380 | # define LC_SHORT_RECONFIG_EN (1 << 11) | ||
381 | # define LC_UPCONFIGURE_SUPPORT (1 << 12) | ||
382 | # define LC_UPCONFIGURE_DIS (1 << 13) | ||
383 | #define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ | ||
384 | # define LC_GEN2_EN_STRAP (1 << 0) | ||
385 | # define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) | ||
386 | # define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) | ||
387 | # define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) | ||
388 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) | ||
389 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 | ||
390 | # define LC_CURRENT_DATA_RATE (1 << 11) | ||
391 | # define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) | ||
392 | # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) | ||
393 | # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) | ||
394 | # define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) | ||
395 | #define MM_CFGREGS_CNTL 0x544c | ||
396 | # define MM_WR_TO_CFG_EN (1 << 3) | ||
397 | #define LINK_CNTL2 0x88 /* F0 */ | ||
398 | # define TARGET_LINK_SPEED_MASK (0xf << 0) | ||
399 | # define SELECTABLE_DEEMPHASIS (1 << 6) | ||
400 | |||
363 | #endif | 401 | #endif |