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 | |
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>
-rw-r--r-- | drivers/gpu/drm/radeon/r300.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 118 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_reg.h | 9 |
6 files changed, 145 insertions, 11 deletions
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 23fee54c3b75..fae5e709f270 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -558,10 +558,7 @@ int rv370_get_pcie_lanes(struct radeon_device *rdev) | |||
558 | 558 | ||
559 | /* FIXME wait for idle */ | 559 | /* FIXME wait for idle */ |
560 | 560 | ||
561 | if (rdev->family < CHIP_R600) | 561 | link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); |
562 | link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
563 | else | ||
564 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
565 | 562 | ||
566 | switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { | 563 | switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { |
567 | case RADEON_PCIE_LC_LINK_WIDTH_X0: | 564 | case RADEON_PCIE_LC_LINK_WIDTH_X0: |
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 | |||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index aff8080026a1..e9fb64c1e20b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1317,6 +1317,14 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); | |||
1317 | (rdev->family == CHIP_RV410) || \ | 1317 | (rdev->family == CHIP_RV410) || \ |
1318 | (rdev->family == CHIP_RS400) || \ | 1318 | (rdev->family == CHIP_RS400) || \ |
1319 | (rdev->family == CHIP_RS480)) | 1319 | (rdev->family == CHIP_RS480)) |
1320 | #define ASIC_IS_X2(rdev) ((rdev->ddev->pdev->device == 0x9441) || \ | ||
1321 | (rdev->ddev->pdev->device == 0x9443) || \ | ||
1322 | (rdev->ddev->pdev->device == 0x944B) || \ | ||
1323 | (rdev->ddev->pdev->device == 0x9506) || \ | ||
1324 | (rdev->ddev->pdev->device == 0x9509) || \ | ||
1325 | (rdev->ddev->pdev->device == 0x950F) || \ | ||
1326 | (rdev->ddev->pdev->device == 0x689C) || \ | ||
1327 | (rdev->ddev->pdev->device == 0x689D)) | ||
1320 | #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) | 1328 | #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) |
1321 | #define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \ | 1329 | #define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \ |
1322 | (rdev->family == CHIP_RS690) || \ | 1330 | (rdev->family == CHIP_RS690) || \ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 3d73fe484f42..53c62404795d 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev) | |||
94 | rdev->mc_rreg = &rs600_mc_rreg; | 94 | rdev->mc_rreg = &rs600_mc_rreg; |
95 | rdev->mc_wreg = &rs600_mc_wreg; | 95 | rdev->mc_wreg = &rs600_mc_wreg; |
96 | } | 96 | } |
97 | if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { | 97 | if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_HEMLOCK)) { |
98 | rdev->pciep_rreg = &r600_pciep_rreg; | 98 | rdev->pciep_rreg = &r600_pciep_rreg; |
99 | rdev->pciep_wreg = &r600_pciep_wreg; | 99 | rdev->pciep_wreg = &r600_pciep_wreg; |
100 | } | 100 | } |
@@ -631,8 +631,8 @@ static struct radeon_asic r600_asic = { | |||
631 | .set_engine_clock = &radeon_atom_set_engine_clock, | 631 | .set_engine_clock = &radeon_atom_set_engine_clock, |
632 | .get_memory_clock = &radeon_atom_get_memory_clock, | 632 | .get_memory_clock = &radeon_atom_get_memory_clock, |
633 | .set_memory_clock = &radeon_atom_set_memory_clock, | 633 | .set_memory_clock = &radeon_atom_set_memory_clock, |
634 | .get_pcie_lanes = &rv370_get_pcie_lanes, | 634 | .get_pcie_lanes = &r600_get_pcie_lanes, |
635 | .set_pcie_lanes = NULL, | 635 | .set_pcie_lanes = &r600_set_pcie_lanes, |
636 | .set_clock_gating = NULL, | 636 | .set_clock_gating = NULL, |
637 | .set_surface_reg = r600_set_surface_reg, | 637 | .set_surface_reg = r600_set_surface_reg, |
638 | .clear_surface_reg = r600_clear_surface_reg, | 638 | .clear_surface_reg = r600_clear_surface_reg, |
@@ -725,8 +725,8 @@ static struct radeon_asic rv770_asic = { | |||
725 | .set_engine_clock = &radeon_atom_set_engine_clock, | 725 | .set_engine_clock = &radeon_atom_set_engine_clock, |
726 | .get_memory_clock = &radeon_atom_get_memory_clock, | 726 | .get_memory_clock = &radeon_atom_get_memory_clock, |
727 | .set_memory_clock = &radeon_atom_set_memory_clock, | 727 | .set_memory_clock = &radeon_atom_set_memory_clock, |
728 | .get_pcie_lanes = &rv370_get_pcie_lanes, | 728 | .get_pcie_lanes = &r600_get_pcie_lanes, |
729 | .set_pcie_lanes = NULL, | 729 | .set_pcie_lanes = &r600_set_pcie_lanes, |
730 | .set_clock_gating = &radeon_atom_set_clock_gating, | 730 | .set_clock_gating = &radeon_atom_set_clock_gating, |
731 | .set_surface_reg = r600_set_surface_reg, | 731 | .set_surface_reg = r600_set_surface_reg, |
732 | .clear_surface_reg = r600_clear_surface_reg, | 732 | .clear_surface_reg = r600_clear_surface_reg, |
@@ -772,8 +772,8 @@ static struct radeon_asic evergreen_asic = { | |||
772 | .set_engine_clock = &radeon_atom_set_engine_clock, | 772 | .set_engine_clock = &radeon_atom_set_engine_clock, |
773 | .get_memory_clock = &radeon_atom_get_memory_clock, | 773 | .get_memory_clock = &radeon_atom_get_memory_clock, |
774 | .set_memory_clock = &radeon_atom_set_memory_clock, | 774 | .set_memory_clock = &radeon_atom_set_memory_clock, |
775 | .get_pcie_lanes = NULL, | 775 | .get_pcie_lanes = &r600_get_pcie_lanes, |
776 | .set_pcie_lanes = NULL, | 776 | .set_pcie_lanes = &r600_set_pcie_lanes, |
777 | .set_clock_gating = NULL, | 777 | .set_clock_gating = NULL, |
778 | .set_surface_reg = r600_set_surface_reg, | 778 | .set_surface_reg = r600_set_surface_reg, |
779 | .clear_surface_reg = r600_clear_surface_reg, | 779 | .clear_surface_reg = r600_clear_surface_reg, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 4970eda1bd41..9ac71b8d1b9d 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -284,6 +284,8 @@ extern void r600_pm_misc(struct radeon_device *rdev); | |||
284 | extern void r600_pm_init_profile(struct radeon_device *rdev); | 284 | extern void r600_pm_init_profile(struct radeon_device *rdev); |
285 | extern void rs780_pm_init_profile(struct radeon_device *rdev); | 285 | extern void rs780_pm_init_profile(struct radeon_device *rdev); |
286 | extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); | 286 | extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); |
287 | extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes); | ||
288 | extern int r600_get_pcie_lanes(struct radeon_device *rdev); | ||
287 | 289 | ||
288 | /* | 290 | /* |
289 | * rv770,rv730,rv710,rv740 | 291 | * rv770,rv730,rv710,rv740 |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 0a310b7f71c3..3369ce984af1 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -320,6 +320,15 @@ | |||
320 | # define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8) | 320 | # define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8) |
321 | # define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9) | 321 | # define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9) |
322 | # define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10) | 322 | # define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10) |
323 | # define R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) | ||
324 | # define R600_PCIE_LC_RENEGOTIATION_SUPPORT (1 << 9) | ||
325 | # define R600_PCIE_LC_RENEGOTIATE_EN (1 << 10) | ||
326 | # define R600_PCIE_LC_SHORT_RECONFIG_EN (1 << 11) | ||
327 | # define R600_PCIE_LC_UPCONFIGURE_SUPPORT (1 << 12) | ||
328 | # define R600_PCIE_LC_UPCONFIGURE_DIS (1 << 13) | ||
329 | |||
330 | #define R600_TARGET_AND_CURRENT_PROFILE_INDEX 0x70c | ||
331 | #define R700_TARGET_AND_CURRENT_PROFILE_INDEX 0x66c | ||
323 | 332 | ||
324 | #define RADEON_CACHE_CNTL 0x1724 | 333 | #define RADEON_CACHE_CNTL 0x1724 |
325 | #define RADEON_CACHE_LINE 0x0f0c /* PCI */ | 334 | #define RADEON_CACHE_LINE 0x0f0c /* PCI */ |