aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/rv770.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/rv770.c')
-rw-r--r--drivers/gpu/drm/radeon/rv770.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 645aa1fd7611..3a264aa3a79a 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -41,6 +41,7 @@
41 41
42static void rv770_gpu_init(struct radeon_device *rdev); 42static void rv770_gpu_init(struct radeon_device *rdev);
43void rv770_fini(struct radeon_device *rdev); 43void rv770_fini(struct radeon_device *rdev);
44static void rv770_pcie_gen2_enable(struct radeon_device *rdev);
44 45
45u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) 46u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
46{ 47{
@@ -1124,6 +1125,9 @@ static int rv770_startup(struct radeon_device *rdev)
1124{ 1125{
1125 int r; 1126 int r;
1126 1127
1128 /* enable pcie gen2 link */
1129 rv770_pcie_gen2_enable(rdev);
1130
1127 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { 1131 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
1128 r = r600_init_microcode(rdev); 1132 r = r600_init_microcode(rdev);
1129 if (r) { 1133 if (r) {
@@ -1362,3 +1366,75 @@ void rv770_fini(struct radeon_device *rdev)
1362 rdev->bios = NULL; 1366 rdev->bios = NULL;
1363 radeon_dummy_page_fini(rdev); 1367 radeon_dummy_page_fini(rdev);
1364} 1368}
1369
1370static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
1371{
1372 u32 link_width_cntl, lanes, speed_cntl, tmp;
1373 u16 link_cntl2;
1374
1375 if (rdev->flags & RADEON_IS_IGP)
1376 return;
1377
1378 if (!(rdev->flags & RADEON_IS_PCIE))
1379 return;
1380
1381 /* x2 cards have a special sequence */
1382 if (ASIC_IS_X2(rdev))
1383 return;
1384
1385 /* advertise upconfig capability */
1386 link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
1387 link_width_cntl &= ~LC_UPCONFIGURE_DIS;
1388 WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
1389 link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
1390 if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) {
1391 lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT;
1392 link_width_cntl &= ~(LC_LINK_WIDTH_MASK |
1393 LC_RECONFIG_ARC_MISSING_ESCAPE);
1394 link_width_cntl |= lanes | LC_RECONFIG_NOW |
1395 LC_RENEGOTIATE_EN | LC_UPCONFIGURE_SUPPORT;
1396 WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
1397 } else {
1398 link_width_cntl |= LC_UPCONFIGURE_DIS;
1399 WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
1400 }
1401
1402 speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
1403 if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
1404 (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1405
1406 tmp = RREG32(0x541c);
1407 WREG32(0x541c, tmp | 0x8);
1408 WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN);
1409 link_cntl2 = RREG16(0x4088);
1410 link_cntl2 &= ~TARGET_LINK_SPEED_MASK;
1411 link_cntl2 |= 0x2;
1412 WREG16(0x4088, link_cntl2);
1413 WREG32(MM_CFGREGS_CNTL, 0);
1414
1415 speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
1416 speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
1417 WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
1418
1419 speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
1420 speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT;
1421 WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
1422
1423 speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
1424 speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
1425 WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
1426
1427 speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
1428 speed_cntl |= LC_GEN2_EN_STRAP;
1429 WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
1430
1431 } else {
1432 link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
1433 /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
1434 if (1)
1435 link_width_cntl |= LC_UPCONFIGURE_DIS;
1436 else
1437 link_width_cntl &= ~LC_UPCONFIGURE_DIS;
1438 WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
1439 }
1440}