Commit 3313e3d4 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: add pcie get/set lane support for r6xx/r7xx/evergreen

Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent f598aa75
...@@ -558,10 +558,7 @@ int rv370_get_pcie_lanes(struct radeon_device *rdev) ...@@ -558,10 +558,7 @@ int rv370_get_pcie_lanes(struct radeon_device *rdev)
/* FIXME wait for idle */ /* FIXME wait for idle */
if (rdev->family < CHIP_R600) link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
else
link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) {
case RADEON_PCIE_LC_LINK_WIDTH_X0: case RADEON_PCIE_LC_LINK_WIDTH_X0:
......
...@@ -3531,3 +3531,121 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) ...@@ -3531,3 +3531,121 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
} else } else
WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
} }
void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes)
{
u32 link_width_cntl, mask, target_reg;
if (rdev->flags & RADEON_IS_IGP)
return;
if (!(rdev->flags & RADEON_IS_PCIE))
return;
/* x2 cards have a special sequence */
if (ASIC_IS_X2(rdev))
return;
/* 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;
if (link_width_cntl & R600_PCIE_LC_UPCONFIGURE_DIS)
return;
link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK |
RADEON_PCIE_LC_RECONFIG_NOW |
R600_PCIE_LC_RENEGOTIATE_EN |
R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE);
link_width_cntl |= mask;
WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
/* 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 (link_width_cntl & R600_PCIE_LC_RENEGOTIATION_SUPPORT)
link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN | R600_PCIE_LC_UPCONFIGURE_SUPPORT;
else
link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE;
WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl |
RADEON_PCIE_LC_RECONFIG_NOW));
if (rdev->family >= CHIP_RV770)
target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX;
else
target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX;
/* wait for lane set to complete */
link_width_cntl = RREG32(target_reg);
while (link_width_cntl == 0xffffffff)
link_width_cntl = RREG32(target_reg);
}
int r600_get_pcie_lanes(struct radeon_device *rdev)
{
u32 link_width_cntl;
if (rdev->flags & RADEON_IS_IGP)
return 0;
if (!(rdev->flags & RADEON_IS_PCIE))
return 0;
/* x2 cards have a special sequence */
if (ASIC_IS_X2(rdev))
return 0;
/* FIXME wait for idle */
link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) {
case RADEON_PCIE_LC_LINK_WIDTH_X0:
return 0;
case RADEON_PCIE_LC_LINK_WIDTH_X1:
return 1;
case RADEON_PCIE_LC_LINK_WIDTH_X2:
return 2;
case RADEON_PCIE_LC_LINK_WIDTH_X4:
return 4;
case RADEON_PCIE_LC_LINK_WIDTH_X8:
return 8;
case RADEON_PCIE_LC_LINK_WIDTH_X16:
default:
return 16;
}
}
...@@ -1317,6 +1317,14 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); ...@@ -1317,6 +1317,14 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
(rdev->family == CHIP_RV410) || \ (rdev->family == CHIP_RV410) || \
(rdev->family == CHIP_RS400) || \ (rdev->family == CHIP_RS400) || \
(rdev->family == CHIP_RS480)) (rdev->family == CHIP_RS480))
#define ASIC_IS_X2(rdev) ((rdev->ddev->pdev->device == 0x9441) || \
(rdev->ddev->pdev->device == 0x9443) || \
(rdev->ddev->pdev->device == 0x944B) || \
(rdev->ddev->pdev->device == 0x9506) || \
(rdev->ddev->pdev->device == 0x9509) || \
(rdev->ddev->pdev->device == 0x950F) || \
(rdev->ddev->pdev->device == 0x689C) || \
(rdev->ddev->pdev->device == 0x689D))
#define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600))
#define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \ #define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \
(rdev->family == CHIP_RS690) || \ (rdev->family == CHIP_RS690) || \
......
...@@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev) ...@@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev)
rdev->mc_rreg = &rs600_mc_rreg; rdev->mc_rreg = &rs600_mc_rreg;
rdev->mc_wreg = &rs600_mc_wreg; rdev->mc_wreg = &rs600_mc_wreg;
} }
if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_HEMLOCK)) {
rdev->pciep_rreg = &r600_pciep_rreg; rdev->pciep_rreg = &r600_pciep_rreg;
rdev->pciep_wreg = &r600_pciep_wreg; rdev->pciep_wreg = &r600_pciep_wreg;
} }
...@@ -631,8 +631,8 @@ static struct radeon_asic r600_asic = { ...@@ -631,8 +631,8 @@ static struct radeon_asic r600_asic = {
.set_engine_clock = &radeon_atom_set_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock,
.get_memory_clock = &radeon_atom_get_memory_clock, .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock,
.get_pcie_lanes = &rv370_get_pcie_lanes, .get_pcie_lanes = &r600_get_pcie_lanes,
.set_pcie_lanes = NULL, .set_pcie_lanes = &r600_set_pcie_lanes,
.set_clock_gating = NULL, .set_clock_gating = NULL,
.set_surface_reg = r600_set_surface_reg, .set_surface_reg = r600_set_surface_reg,
.clear_surface_reg = r600_clear_surface_reg, .clear_surface_reg = r600_clear_surface_reg,
...@@ -725,8 +725,8 @@ static struct radeon_asic rv770_asic = { ...@@ -725,8 +725,8 @@ static struct radeon_asic rv770_asic = {
.set_engine_clock = &radeon_atom_set_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock,
.get_memory_clock = &radeon_atom_get_memory_clock, .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock,
.get_pcie_lanes = &rv370_get_pcie_lanes, .get_pcie_lanes = &r600_get_pcie_lanes,
.set_pcie_lanes = NULL, .set_pcie_lanes = &r600_set_pcie_lanes,
.set_clock_gating = &radeon_atom_set_clock_gating, .set_clock_gating = &radeon_atom_set_clock_gating,
.set_surface_reg = r600_set_surface_reg, .set_surface_reg = r600_set_surface_reg,
.clear_surface_reg = r600_clear_surface_reg, .clear_surface_reg = r600_clear_surface_reg,
...@@ -772,8 +772,8 @@ static struct radeon_asic evergreen_asic = { ...@@ -772,8 +772,8 @@ static struct radeon_asic evergreen_asic = {
.set_engine_clock = &radeon_atom_set_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock,
.get_memory_clock = &radeon_atom_get_memory_clock, .get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock,
.get_pcie_lanes = NULL, .get_pcie_lanes = &r600_get_pcie_lanes,
.set_pcie_lanes = NULL, .set_pcie_lanes = &r600_set_pcie_lanes,
.set_clock_gating = NULL, .set_clock_gating = NULL,
.set_surface_reg = r600_set_surface_reg, .set_surface_reg = r600_set_surface_reg,
.clear_surface_reg = r600_clear_surface_reg, .clear_surface_reg = r600_clear_surface_reg,
......
...@@ -284,6 +284,8 @@ extern void r600_pm_misc(struct radeon_device *rdev); ...@@ -284,6 +284,8 @@ extern void r600_pm_misc(struct radeon_device *rdev);
extern void r600_pm_init_profile(struct radeon_device *rdev); extern void r600_pm_init_profile(struct radeon_device *rdev);
extern void rs780_pm_init_profile(struct radeon_device *rdev); extern void rs780_pm_init_profile(struct radeon_device *rdev);
extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); extern void r600_pm_get_dynpm_state(struct radeon_device *rdev);
extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes);
extern int r600_get_pcie_lanes(struct radeon_device *rdev);
/* /*
* rv770,rv730,rv710,rv740 * rv770,rv730,rv710,rv740
......
...@@ -320,6 +320,15 @@ ...@@ -320,6 +320,15 @@
# define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8) # define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8)
# define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9) # define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9)
# define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10) # define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10)
# define R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7)
# define R600_PCIE_LC_RENEGOTIATION_SUPPORT (1 << 9)
# define R600_PCIE_LC_RENEGOTIATE_EN (1 << 10)
# define R600_PCIE_LC_SHORT_RECONFIG_EN (1 << 11)
# define R600_PCIE_LC_UPCONFIGURE_SUPPORT (1 << 12)
# define R600_PCIE_LC_UPCONFIGURE_DIS (1 << 13)
#define R600_TARGET_AND_CURRENT_PROFILE_INDEX 0x70c
#define R700_TARGET_AND_CURRENT_PROFILE_INDEX 0x66c
#define RADEON_CACHE_CNTL 0x1724 #define RADEON_CACHE_CNTL 0x1724
#define RADEON_CACHE_LINE 0x0f0c /* PCI */ #define RADEON_CACHE_LINE 0x0f0c /* PCI */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment