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 at gmail.com>
Cc: stable at 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

Reply via email to