Ported from DDX

Signed-off-by: Rafał Miłecki <[email protected]>
---
 drivers/gpu/drm/radeon/r600.c        |   76 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_asic.h |    5 +-
 drivers/gpu/drm/radeon/radeon_reg.h  |    5 ++
 3 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 694a4c5..e06eaba 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2863,6 +2863,82 @@ restart_ih:
        return IRQ_HANDLED;
 }
 
+void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes)
+{
+       uint32_t link_width_cntl, mask, target_reg;
+
+       if (rdev->flags & RADEON_IS_IGP)
+               return;
+
+       if (!(rdev->flags & RADEON_IS_PCIE))
+               return;
+
+       /* FIXME check for multi GPU */
+
+       /* FIXME wait for idle */
+
+       switch (lanes) {
+       case 0:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X0;
+               break;
+       case 1:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X1;
+               break;
+       case 2:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X2;
+               break;
+       case 4:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X4;
+               break;
+       case 8:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X8;
+               break;
+       case 12:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X12;
+               break;
+       case 16:
+       default:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X16;
+               break;
+       }
+
+       link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+
+       if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) ==
+           (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT))
+               return;
+
+       link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK |
+                            RADEON_PCIE_LC_RECONFIG_NOW |
+                            R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE |
+                            R600_PCIE_LC_SHORT_RECONFIG_EN |
+                            R600_PCIE_LC_RENEGOTIATE_EN);
+       link_width_cntl |= mask;
+#if 0
+       /* some northbridges can renegotiate the link rather than requiring
+        * a complete re-config.
+        * e.g., AMD 780/790 northbridges (pci ids: 0x5956, 0x5957, 0x5958, 
etc.)
+        */
+       if (northbridge can renegotiate)
+               link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN;
+       else
+#endif
+               link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE;
+
+       WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+       WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL,
+                       (link_width_cntl | RADEON_PCIE_LC_RECONFIG_NOW));
+
+       /* wait for lane set to complete */
+       if (rdev->family >= CHIP_RV770)
+               target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX;
+       else
+               target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX;
+       link_width_cntl = RREG32(target_reg);
+       while (link_width_cntl == 0xffffffff)
+               link_width_cntl = RREG32(target_reg);
+}
+
 /*
  * Debugfs info
  */
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 4572a66..d70b80b 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -601,6 +601,7 @@ bool r600_hpd_sense(struct radeon_device *rdev, enum 
radeon_hpd_id hpd);
 void r600_hpd_set_polarity(struct radeon_device *rdev,
                           enum radeon_hpd_id hpd);
 extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo 
*bo);
+void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes);
 
 static struct radeon_asic r600_asic = {
        .init = &r600_init,
@@ -627,7 +628,7 @@ static struct radeon_asic r600_asic = {
        .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = NULL,
+       .set_pcie_lanes = &r600_set_pcie_lanes,
        .set_clock_gating = NULL,
        .set_surface_reg = r600_set_surface_reg,
        .clear_surface_reg = r600_clear_surface_reg,
@@ -673,7 +674,7 @@ static struct radeon_asic rv770_asic = {
        .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = NULL,
+       .set_pcie_lanes = &r600_set_pcie_lanes,
        .set_clock_gating = &radeon_atom_set_clock_gating,
        .set_surface_reg = r600_set_surface_reg,
        .clear_surface_reg = r600_clear_surface_reg,
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h 
b/drivers/gpu/drm/radeon/radeon_reg.h
index 5c0dc08..2090aeb 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -317,9 +317,14 @@
 #       define RADEON_PCIE_LC_LINK_WIDTH_X16       6
 #       define RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT  4
 #       define RADEON_PCIE_LC_LINK_WIDTH_RD_MASK   0x70
+#       define R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE   (1 << 7)
 #       define RADEON_PCIE_LC_RECONFIG_NOW         (1 << 8)
 #       define RADEON_PCIE_LC_RECONFIG_LATER       (1 << 9)
 #       define RADEON_PCIE_LC_SHORT_RECONFIG_EN    (1 << 10)
+#       define R600_PCIE_LC_RENEGOTIATE_EN         (1 << 10)
+#       define R600_PCIE_LC_SHORT_RECONFIG_EN      (1 << 11)
+#define R600_TARGET_AND_CURRENT_PROFILE_INDEX      0x70c
+#define R700_TARGET_AND_CURRENT_PROFILE_INDEX      0x66c
 
 #define RADEON_CACHE_CNTL                   0x1724
 #define RADEON_CACHE_LINE                   0x0f0c /* PCI */
-- 
1.6.4.2


------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to