summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2008-09-18 16:07:41 -0400
committerAlex Deucher <alexdeucher@gmail.com>2008-09-18 16:07:41 -0400
commit34af71c42a66e5ef6a9a08250ca541030ca3cc4f (patch)
tree13d9f716250ec5fd5491571b43f00cda98bd0727 /linux-core
parente1e782af5ddafdd24a4cf741139bb0b8e682e543 (diff)
radeon: add function to configure PCIE lanes
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/radeon_pm.c60
-rw-r--r--linux-core/radeon_reg.h18
2 files changed, 78 insertions, 0 deletions
diff --git a/linux-core/radeon_pm.c b/linux-core/radeon_pm.c
index e9a6130a..5d14384c 100644
--- a/linux-core/radeon_pm.c
+++ b/linux-core/radeon_pm.c
@@ -178,3 +178,63 @@ int radeon_resume(struct drm_device *dev)
return 0;
}
+
+bool radeon_set_pcie_lanes(struct drm_device *dev, int lanes)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ uint32_t link_width_cntl, mask;
+
+ /* 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 = RADEON_READ_PCIE(dev_priv, 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 true;
+
+ link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK |
+ RADEON_PCIE_LC_RECONFIG_NOW |
+ RADEON_PCIE_LC_RECONFIG_LATER |
+ RADEON_PCIE_LC_SHORT_RECONFIG_EN);
+ link_width_cntl |= mask;
+ RADEON_WRITE_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+ RADEON_WRITE_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl | RADEON_PCIE_LC_RECONFIG_NOW);
+
+ /* wait for lane set to complete */
+ link_width_cntl = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+ while (link_width_cntl == 0xffffffff)
+ link_width_cntl = RADEON_READ_PCIE(dev_priv, 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 true;
+ else
+ return false;
+}
+
diff --git a/linux-core/radeon_reg.h b/linux-core/radeon_reg.h
index e7f30817..c4bc7a80 100644
--- a/linux-core/radeon_reg.h
+++ b/linux-core/radeon_reg.h
@@ -274,6 +274,24 @@
#define RADEON_BUS_CNTL1 0x0034
# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4)
+//#define RADEON_PCIE_INDEX 0x0030
+//#define RADEON_PCIE_DATA 0x0034
+#define RADEON_PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE */
+# define RADEON_PCIE_LC_LINK_WIDTH_SHIFT 0
+# define RADEON_PCIE_LC_LINK_WIDTH_MASK 0x7
+# define RADEON_PCIE_LC_LINK_WIDTH_X0 0
+# define RADEON_PCIE_LC_LINK_WIDTH_X1 1
+# define RADEON_PCIE_LC_LINK_WIDTH_X2 2
+# define RADEON_PCIE_LC_LINK_WIDTH_X4 3
+# define RADEON_PCIE_LC_LINK_WIDTH_X8 4
+# define RADEON_PCIE_LC_LINK_WIDTH_X12 5
+# 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 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 RADEON_CACHE_CNTL 0x1724
#define RADEON_CACHE_LINE 0x0f0c /* PCI */
#define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */