From c88cf9c2463629ab0cef7df8ade34750cde9b40a Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexdeucher@gmail.com>
Date: Wed, 9 Feb 2011 17:05:07 -0500
Subject: [PATCH] drm/radeon/kms: pll quirk cleanup

Default to legacy pll algo, add quirks for specific
regressions.  Fixes regressions reported in:
https://bugzilla.kernel.org/show_bug.cgi?id=26552

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Cc: stable@kernel.org
---
 drivers/gpu/drm/radeon/atombios_crtc.c |   52 +++++++++++++++++++++++++------
 drivers/gpu/drm/radeon/radeon_mode.h   |    8 +++++
 2 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 4a505ba..cc6bdd8 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -31,6 +31,11 @@
 #include "atom.h"
 #include "atom-bits.h"
 
+static enum radeon_pll_algo
+atombios_crtc_pick_pll_algo(struct drm_crtc *crtc,
+			    struct drm_display_mode *mode,
+			    uint32_t active_device);
+
 static void atombios_overscan_setup(struct drm_crtc *crtc,
 				    struct drm_display_mode *mode,
 				    struct drm_display_mode *adjusted_mode)
@@ -519,6 +524,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
 
 	/* reset the pll flags */
 	pll->flags = 0;
+	pll->algo = RADEON_PLL_ALGO_LEGACY;
 
 	if (ASIC_IS_AVIVO(rdev)) {
 		if ((rdev->family == CHIP_RS600) ||
@@ -584,6 +590,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
 				if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
 					pll->flags |= RADEON_PLL_USE_REF_DIV;
 			}
+			pll->algo = atombios_crtc_pick_pll_algo(crtc, mode, radeon_encoder->active_device);
 			break;
 		}
 	}
@@ -839,29 +846,54 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
-#define RADEON_PLL_ALGO_LEGACY 0
-#define RADEON_PLL_ALGO_AVIVO  1
 
-static int atombios_crtc_pick_pll_algo(struct drm_crtc *crtc, struct drm_display_mode *mode)
+static enum radeon_pll_algo
+atombios_crtc_pick_pll_algo(struct drm_crtc *crtc,
+			    struct drm_display_mode *mode,
+			    uint32_t active_device)
 {
 	struct drm_device *dev = crtc->dev;
-	struct radeon_device *rdev = dev->dev_private;
 
 	/* board specific quirks */
-	/* funky macbooks */
+
+	/* legacy algo */
+	/* macbookpro2,2 */
 	if ((dev->pdev->device == 0x71C5) &&
 	    (dev->pdev->subsystem_vendor == 0x106b) &&
 	    (dev->pdev->subsystem_device == 0x0080)) {
 		return RADEON_PLL_ALGO_LEGACY;
 	}
 
-	/* defaults  */
-	/* rv515 seems happier with the old algo */
-	if (rdev->family == CHIP_RV515)
+	/* Thinkpad T60 */
+	if ((dev->pdev->device == 0x7145) &&
+	    (dev->pdev->subsystem_vendor == 0x17aa) &&
+	    (dev->pdev->subsystem_device == 0x2006)) {
 		return RADEON_PLL_ALGO_LEGACY;
-	else if (ASIC_IS_AVIVO(rdev))
+	}
+
+	/* Acer RS880 */
+	if ((dev->pdev->device == 0x9712) &&
+	    (dev->pdev->subsystem_vendor == 0x1025) &&
+	    (dev->pdev->subsystem_device == 0x027d)) {
+		return RADEON_PLL_ALGO_LEGACY;
+	}
+
+	/* avivo algo */
+	/* PC Partner RV630 */
+	if ((dev->pdev->device == 0x9589) &&
+	    (dev->pdev->subsystem_vendor == 0x174b) &&
+	    (dev->pdev->subsystem_device == 0xe410)) {
 		return RADEON_PLL_ALGO_AVIVO;
+	}
+
+	/* Toshiba Satellite A100 */
+	if ((dev->pdev->device == 0x71C5) &&
+	    (dev->pdev->subsystem_vendor == 0x1179) &&
+	    (dev->pdev->subsystem_device == 0xff10)) {
+		return RADEON_PLL_ALGO_AVIVO;
+	}
 
+	/* default to the legacy algo */
 	return RADEON_PLL_ALGO_LEGACY;
 }
 
@@ -983,7 +1015,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
 	/* adjust pixel clock as needed */
 	adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
 
-	switch (atombios_crtc_pick_pll_algo(crtc, mode)) {
+	switch (pll->algo) {
 	case RADEON_PLL_ALGO_LEGACY:
 	default:
 		radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index a670caa..1d760c6 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -151,6 +151,12 @@ struct radeon_tmds_pll {
 #define RADEON_PLL_IS_LCD               (1 << 13)
 #define RADEON_PLL_PREFER_MINM_OVER_MAXP (1 << 14)
 
+/* pll algo */
+enum radeon_pll_algo {
+	RADEON_PLL_ALGO_LEGACY,
+	RADEON_PLL_ALGO_AVIVO
+};
+
 struct radeon_pll {
 	/* reference frequency */
 	uint32_t reference_freq;
@@ -183,6 +189,8 @@ struct radeon_pll {
 
 	/* pll id */
 	uint32_t id;
+	/* pll algo */
+	enum radeon_pll_algo algo;
 };
 
 struct radeon_i2c_chan {
-- 
1.7.1.1

