radeon: add function to configure PCIE lanes

main
Alex Deucher 2008-09-18 16:07:41 -04:00
parent e1e782af5d
commit 34af71c42a
4 changed files with 80 additions and 1 deletions

View File

@ -178,3 +178,63 @@ int radeon_resume(struct drm_device *dev)
return 0; 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;
}

View File

@ -274,6 +274,24 @@
#define RADEON_BUS_CNTL1 0x0034 #define RADEON_BUS_CNTL1 0x0034
# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) # 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_CNTL 0x1724
#define RADEON_CACHE_LINE 0x0f0c /* PCI */ #define RADEON_CACHE_LINE 0x0f0c /* PCI */
#define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */ #define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */

View File

@ -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); 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); RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
return RADEON_READ(RADEON_PCIE_DATA); return RADEON_READ(RADEON_PCIE_DATA);

View File

@ -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 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 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) \ #define RADEON_WRITE_P(reg, val, mask) \
do { \ do { \