Commit 0331f674 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: add support pll selection for DCE8 (v4)



v2: make PPLL0 is available for non-DP on CI
v3: rebase changes, update documentation
v4: fix kabini

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8542c12b
Loading
Loading
Loading
Loading
+47 −1
Original line number Diff line number Diff line
@@ -1621,6 +1621,12 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
 *
 * Asic specific PLL information
 *
 * DCE 8.x
 * KB/KV
 * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP)
 * CI
 * - PPLL0, PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
 *
 * DCE 6.1
 * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
 * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
@@ -1647,7 +1653,47 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
	u32 pll_in_use;
	int pll;

	if (ASIC_IS_DCE61(rdev)) {
	if (ASIC_IS_DCE8(rdev)) {
		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
			if (rdev->clock.dp_extclk)
				/* skip PPLL programming if using ext clock */
				return ATOM_PPLL_INVALID;
			else {
				/* use the same PPLL for all DP monitors */
				pll = radeon_get_shared_dp_ppll(crtc);
				if (pll != ATOM_PPLL_INVALID)
					return pll;
			}
		} else {
			/* use the same PPLL for all monitors with the same clock */
			pll = radeon_get_shared_nondp_ppll(crtc);
			if (pll != ATOM_PPLL_INVALID)
				return pll;
		}
		/* otherwise, pick one of the plls */
		if ((rdev->family == CHIP_KAVERI) ||
		    (rdev->family == CHIP_KABINI)) {
			/* KB/KV has PPLL1 and PPLL2 */
			pll_in_use = radeon_get_pll_use_mask(crtc);
			if (!(pll_in_use & (1 << ATOM_PPLL2)))
				return ATOM_PPLL2;
			if (!(pll_in_use & (1 << ATOM_PPLL1)))
				return ATOM_PPLL1;
			DRM_ERROR("unable to allocate a PPLL\n");
			return ATOM_PPLL_INVALID;
		} else {
			/* CI has PPLL0, PPLL1, and PPLL2 */
			pll_in_use = radeon_get_pll_use_mask(crtc);
			if (!(pll_in_use & (1 << ATOM_PPLL2)))
				return ATOM_PPLL2;
			if (!(pll_in_use & (1 << ATOM_PPLL1)))
				return ATOM_PPLL1;
			if (!(pll_in_use & (1 << ATOM_PPLL0)))
				return ATOM_PPLL0;
			DRM_ERROR("unable to allocate a PPLL\n");
			return ATOM_PPLL_INVALID;
		}
	} else if (ASIC_IS_DCE61(rdev)) {
		struct radeon_encoder_atom_dig *dig =
			radeon_encoder->enc_priv;