summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/radeon_pm.c60
-rw-r--r--linux-core/radeon_reg.h18
-rw-r--r--shared-core/radeon_cp.c2
-rw-r--r--shared-core/radeon_drv.h1
4 files changed, 80 insertions, 1 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 */
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 1ad005b7..b934d3bc 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -235,7 +235,7 @@ void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t da
radeon_pll_errata_after_data(dev_priv);
}
-static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
+u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
{
RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
return RADEON_READ(RADEON_PCIE_DATA);
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index 82d9d001..25a07e30 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -1298,6 +1298,7 @@ int radeon_resume(struct drm_device *dev);
extern u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr);
extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data);
+extern u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr);
#define RADEON_WRITE_P(reg, val, mask) \
do { \