diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2011-01-06 18:49:34 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-01-06 23:11:13 -0500 |
commit | 3313e3d4333ccbf8bd7c816775cfe9aca623bd8a (patch) | |
tree | 541755e1eb2f582dc6e2d3cf7abedab0820377d9 /drivers/gpu/drm/radeon/r600.c | |
parent | f598aa7593427ffe3a61e7767c34bd695a5e7ed0 (diff) |
drm/radeon/kms: add pcie get/set lane support for r6xx/r7xx/evergreen
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 | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 279794c391e9..60ad8c03081a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -3531,3 +3531,121 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
3531 | } else | 3531 | } else |
3532 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | 3532 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); |
3533 | } | 3533 | } |
3534 | |||
3535 | void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes) | ||
3536 | { | ||
3537 | u32 link_width_cntl, mask, target_reg; | ||
3538 | |||
3539 | if (rdev->flags & RADEON_IS_IGP) | ||
3540 | return; | ||
3541 | |||
3542 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3543 | return; | ||
3544 | |||
3545 | /* x2 cards have a special sequence */ | ||
3546 | if (ASIC_IS_X2(rdev)) | ||
3547 | return; | ||
3548 | |||
3549 | /* FIXME wait for idle */ | ||
3550 | |||
3551 | switch (lanes) { | ||
3552 | case 0: | ||
3553 | mask = RADEON_PCIE_LC_LINK_WIDTH_X0; | ||
3554 | break; | ||
3555 | case 1: | ||
3556 | mask = RADEON_PCIE_LC_LINK_WIDTH_X1; | ||
3557 | break; | ||
3558 | case 2: | ||
3559 | mask = RADEON_PCIE_LC_LINK_WIDTH_X2; | ||
3560 | break; | ||
3561 | case 4: | ||
3562 | mask = RADEON_PCIE_LC_LINK_WIDTH_X4; | ||
3563 | break; | ||
3564 | case 8: | ||
3565 | mask = RADEON_PCIE_LC_LINK_WIDTH_X8; | ||
3566 | break; | ||
3567 | case 12: | ||
3568 | mask = RADEON_PCIE_LC_LINK_WIDTH_X12; | ||
3569 | break; | ||
3570 | case 16: | ||
3571 | default: | ||
3572 | mask = RADEON_PCIE_LC_LINK_WIDTH_X16; | ||
3573 | break; | ||
3574 | } | ||
3575 | |||
3576 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
3577 | |||
3578 | if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == | ||
3579 | (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) | ||
3580 | return; | ||
3581 | |||
3582 | if (link_width_cntl & R600_PCIE_LC_UPCONFIGURE_DIS) | ||
3583 | return; | ||
3584 | |||
3585 | link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | | ||
3586 | RADEON_PCIE_LC_RECONFIG_NOW | | ||
3587 | R600_PCIE_LC_RENEGOTIATE_EN | | ||
3588 | R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
3589 | link_width_cntl |= mask; | ||
3590 | |||
3591 | WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3592 | |||
3593 | /* some northbridges can renegotiate the link rather than requiring | ||
3594 | * a complete re-config. | ||
3595 | * e.g., AMD 780/790 northbridges (pci ids: 0x5956, 0x5957, 0x5958, etc.) | ||
3596 | */ | ||
3597 | if (link_width_cntl & R600_PCIE_LC_RENEGOTIATION_SUPPORT) | ||
3598 | link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN | R600_PCIE_LC_UPCONFIGURE_SUPPORT; | ||
3599 | else | ||
3600 | link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE; | ||
3601 | |||
3602 | WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl | | ||
3603 | RADEON_PCIE_LC_RECONFIG_NOW)); | ||
3604 | |||
3605 | if (rdev->family >= CHIP_RV770) | ||
3606 | target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX; | ||
3607 | else | ||
3608 | target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX; | ||
3609 | |||
3610 | /* wait for lane set to complete */ | ||
3611 | link_width_cntl = RREG32(target_reg); | ||
3612 | while (link_width_cntl == 0xffffffff) | ||
3613 | link_width_cntl = RREG32(target_reg); | ||
3614 | |||
3615 | } | ||
3616 | |||
3617 | int r600_get_pcie_lanes(struct radeon_device *rdev) | ||
3618 | { | ||
3619 | u32 link_width_cntl; | ||
3620 | |||
3621 | if (rdev->flags & RADEON_IS_IGP) | ||
3622 | return 0; | ||
3623 | |||
3624 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3625 | return 0; | ||
3626 | |||
3627 | /* x2 cards have a special sequence */ | ||
3628 | if (ASIC_IS_X2(rdev)) | ||
3629 | return 0; | ||
3630 | |||
3631 | /* FIXME wait for idle */ | ||
3632 | |||
3633 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
3634 | |||
3635 | switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { | ||
3636 | case RADEON_PCIE_LC_LINK_WIDTH_X0: | ||
3637 | return 0; | ||
3638 | case RADEON_PCIE_LC_LINK_WIDTH_X1: | ||
3639 | return 1; | ||
3640 | case RADEON_PCIE_LC_LINK_WIDTH_X2: | ||
3641 | return 2; | ||
3642 | case RADEON_PCIE_LC_LINK_WIDTH_X4: | ||
3643 | return 4; | ||
3644 | case RADEON_PCIE_LC_LINK_WIDTH_X8: | ||
3645 | return 8; | ||
3646 | case RADEON_PCIE_LC_LINK_WIDTH_X16: | ||
3647 | default: | ||
3648 | return 16; | ||
3649 | } | ||
3650 | } | ||
3651 | |||