aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2011-01-06 18:49:34 -0500
committerDave Airlie <airlied@redhat.com>2011-01-06 23:11:13 -0500
commit3313e3d4333ccbf8bd7c816775cfe9aca623bd8a (patch)
tree541755e1eb2f582dc6e2d3cf7abedab0820377d9
parentf598aa7593427ffe3a61e7767c34bd695a5e7ed0 (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.c5
-rw-r--r--drivers/gpu/drm/radeon/r600.c118
-rw-r--r--drivers/gpu/drm/radeon/radeon.h8
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_reg.h9
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
3535void 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
3617int 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);
284extern void r600_pm_init_profile(struct radeon_device *rdev); 284extern void r600_pm_init_profile(struct radeon_device *rdev);
285extern void rs780_pm_init_profile(struct radeon_device *rdev); 285extern void rs780_pm_init_profile(struct radeon_device *rdev);
286extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); 286extern void r600_pm_get_dynpm_state(struct radeon_device *rdev);
287extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes);
288extern 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 */