From 0331f6749eeecc551abb893a17bbd99eb1cd0e18 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 14 Sep 2012 11:57:21 -0400 Subject: [PATCH] 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: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 48 +++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 586c452e623e..590e4eb5f074 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -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;