Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5445a17 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: update r600 set/get pcie lane config



Updated to the preferred programming sequence.

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 492d2b61
Loading
Loading
Loading
Loading
+15 −42
Original line number Diff line number Diff line
@@ -4523,7 +4523,7 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)

void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes)
{
	u32 link_width_cntl, mask, target_reg;
	u32 link_width_cntl, mask;

	if (rdev->flags & RADEON_IS_IGP)
		return;
@@ -4535,7 +4535,7 @@ void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes)
	if (ASIC_IS_X2(rdev))
		return;

	/* FIXME wait for idle */
	radeon_gui_idle(rdev);

	switch (lanes) {
	case 0:
@@ -4554,53 +4554,24 @@ void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes)
		mask = RADEON_PCIE_LC_LINK_WIDTH_X8;
		break;
	case 12:
		/* not actually supported */
		mask = RADEON_PCIE_LC_LINK_WIDTH_X12;
		break;
	case 16:
	default:
		mask = RADEON_PCIE_LC_LINK_WIDTH_X16;
		break;
	default:
		DRM_ERROR("invalid pcie lane request: %d\n", lanes);
		return;
	}

	link_width_cntl = RREG32_PCIE_PORT(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 |
	link_width_cntl &= ~RADEON_PCIE_LC_LINK_WIDTH_MASK;
	link_width_cntl |= mask << RADEON_PCIE_LC_LINK_WIDTH_SHIFT;
	link_width_cntl |= (RADEON_PCIE_LC_RECONFIG_NOW |
			    R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE);
	link_width_cntl |= mask;

	WREG32_PCIE_PORT(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_PORT(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)
@@ -4617,13 +4588,11 @@ int r600_get_pcie_lanes(struct radeon_device *rdev)
	if (ASIC_IS_X2(rdev))
		return 0;

	/* FIXME wait for idle */
	radeon_gui_idle(rdev);

	link_width_cntl = RREG32_PCIE_PORT(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:
@@ -4632,6 +4601,10 @@ int r600_get_pcie_lanes(struct radeon_device *rdev)
		return 4;
	case RADEON_PCIE_LC_LINK_WIDTH_X8:
		return 8;
	case RADEON_PCIE_LC_LINK_WIDTH_X12:
		/* not actually supported */
		return 12;
	case RADEON_PCIE_LC_LINK_WIDTH_X0:
	case RADEON_PCIE_LC_LINK_WIDTH_X16:
	default:
		return 16;