3.2-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Alex Deucher <alexander.deuc...@amd.com>

commit 2f1f4d9b60396d2df4cff829bd5376ffc8ed9a2c upstream.

This reverts commit 985f61f7ee647ad570c05eab0b74915da2ac8e19.

This commit fixed certain cases, but ended up regressing others
due to limitations in the current KMS API.  A proper fix is too
invasive for 3.6.  Push it back to 3.7.

Reported-by: Andres Freund <and...@anarazel.de>
Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
[bwh: Backported to 3.2: drop the DCE6 case]
Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
---
 drivers/gpu/drm/radeon/atombios_crtc.c |  163 +++++++-------------------------
 1 file changed, 34 insertions(+), 129 deletions(-)

--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1446,98 +1446,14 @@ static void radeon_legacy_atom_fixup(str
        }
 }
 
-/**
- * radeon_get_pll_use_mask - look up a mask of which pplls are in use
- *
- * @crtc: drm crtc
- *
- * Returns the mask of which PPLLs (Pixel PLLs) are in use.
- */
-static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_crtc *test_crtc;
-       struct radeon_crtc *radeon_test_crtc;
-       u32 pll_in_use = 0;
-
-       list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
-               if (crtc == test_crtc)
-                       continue;
-
-               radeon_test_crtc = to_radeon_crtc(test_crtc);
-               if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
-                       pll_in_use |= (1 << radeon_test_crtc->pll_id);
-       }
-       return pll_in_use;
-}
-
-/**
- * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
- *
- * @crtc: drm crtc
- *
- * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
- * also in DP mode.  For DP, a single PPLL can be used for all DP
- * crtcs/encoders.
- */
-static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_encoder *test_encoder;
-       struct radeon_crtc *radeon_test_crtc;
-
-       list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) 
{
-               if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
-                       if 
(ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
-                               /* for DP use the same PLL for all */
-                               radeon_test_crtc = 
to_radeon_crtc(test_encoder->crtc);
-                               if (radeon_test_crtc->pll_id != 
ATOM_PPLL_INVALID)
-                                       return radeon_test_crtc->pll_id;
-                       }
-               }
-       }
-       return ATOM_PPLL_INVALID;
-}
-
-/**
- * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
- *
- * @crtc: drm crtc
- *
- * Returns the PPLL (Pixel PLL) to be used by the crtc.  For DP monitors
- * a single PPLL can be used for all DP crtcs/encoders.  For non-DP
- * monitors a dedicated PPLL must be used.  If a particular board has
- * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
- * as there is no need to program the PLL itself.  If we are not able to
- * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
- * avoid messing up an existing monitor.
- *
- * Asic specific PLL information
- *
- * 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)
- *
- * DCE 6.0
- * - PPLL0 is available to all UNIPHY (DP only)
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- * DCE 5.0
- * - DCPLL is available to all UNIPHY (DP only)
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- * DCE 3.0/4.0/4.1
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- */
 static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct drm_encoder *test_encoder;
-       u32 pll_in_use;
-       int pll;
+       struct drm_crtc *test_crtc;
+       uint32_t pll_in_use = 0;
 
        if (ASIC_IS_DCE4(rdev)) {
                list_for_each_entry(test_encoder, 
&dev->mode_config.encoder_list, head) {
@@ -1545,7 +1461,7 @@ static int radeon_atom_pick_pll(struct d
                                /* in DP mode, the DP ref clock can come from 
PPLL, DCPLL, or ext clock,
                                 * depending on the asic:
                                 * DCE4: PPLL or ext clock
-                                * DCE5: PPLL, DCPLL, or ext clock
+                                * DCE5: DCPLL or ext clock
                                 *
                                 * Setting ATOM_PPLL_INVALID will cause 
SetPixelClock to skip
                                 * PPLL/DCPLL programming and only program the 
DP DTO for the
@@ -1553,31 +1469,29 @@ static int radeon_atom_pick_pll(struct d
                                 */
                                if 
(ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
                                        if (rdev->clock.dp_extclk)
-                                               /* skip PPLL programming if 
using ext clock */
                                                return ATOM_PPLL_INVALID;
                                        else if (ASIC_IS_DCE5(rdev))
-                                               /* use DCPLL for all DP */
                                                return ATOM_DCPLL;
-                                       else {
-                                               /* use the same PPLL for all DP 
monitors */
-                                               pll = 
radeon_get_shared_dp_ppll(crtc);
-                                               if (pll != ATOM_PPLL_INVALID)
-                                                       return pll;
-                                       }
                                }
-                               break;
                        }
                }
-               /* all other cases */
-               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)))
+
+               /* otherwise, pick one of the plls */
+               list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, 
head) {
+                       struct radeon_crtc *radeon_test_crtc;
+
+                       if (crtc == test_crtc)
+                               continue;
+
+                       radeon_test_crtc = to_radeon_crtc(test_crtc);
+                       if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
+                           (radeon_test_crtc->pll_id <= ATOM_PPLL2))
+                               pll_in_use |= (1 << radeon_test_crtc->pll_id);
+               }
+               if (!(pll_in_use & 1))
                        return ATOM_PPLL1;
-               DRM_ERROR("unable to allocate a PPLL\n");
-               return ATOM_PPLL_INVALID;
+               return ATOM_PPLL2;
        } else
-               /* use PPLL1 or PPLL2 */
                return radeon_crtc->crtc_id;
 
 }
@@ -1696,7 +1610,7 @@ static void atombios_crtc_disable(struct
                break;
        }
 done:
-       radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+       radeon_crtc->pll_id = -1;
 }
 
 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -1745,6 +1659,6 @@ void radeon_atombios_init_crtc(struct dr
                else
                        radeon_crtc->crtc_offset = 0;
        }
-       radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+       radeon_crtc->pll_id = -1;
        drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
 }


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to