drm/radeon/kms: further spread spectrum fixes
authorAlex Deucher <alexdeucher@gmail.com>
Mon, 8 Mar 2010 22:10:41 +0000 (17:10 -0500)
committerDave Airlie <airlied@redhat.com>
Sun, 14 Mar 2010 23:57:12 +0000 (09:57 +1000)
Adjust modeset ordering to fix spread spectrum.
The spread spectrum command table relies on the
crtc routing to already be set in order to work
properly on some asics.

Should fix fdo bug 25741.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/radeon_encoders.c

index a8cd637d92faf85f5881de3c27352cf27bcdba21..7c30e2e74c8593ef0cd9bb119992cb20bea6ad1a 100644 (file)
@@ -1127,9 +1127,6 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
 
        /* TODO color tiling */
 
-       /* pick pll */
-       radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
-
        atombios_disable_ss(crtc);
        /* always set DCPLL */
        if (ASIC_IS_DCE4(rdev))
@@ -1164,6 +1161,11 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
 
 static void atombios_crtc_prepare(struct drm_crtc *crtc)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+       /* pick pll */
+       radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
+
        atombios_lock_crtc(crtc, ATOM_ENABLE);
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
index bc926ea0a530e014c2b075fed8ac35e0a94d04ae..4eae30cc521341c1dc3357034192ac77b6bb4717 100644 (file)
@@ -1216,6 +1216,9 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
        }
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+       /* update scratch regs with new routing */
+       radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
 }
 
 static void
@@ -1326,19 +1329,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
 
-       if (radeon_encoder->active_device &
-           (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
-               struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-               if (dig)
-                       dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
-       }
        radeon_encoder->pixel_clock = adjusted_mode->clock;
 
-       radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
-       atombios_set_encoder_crtc_source(encoder);
-
        if (ASIC_IS_AVIVO(rdev)) {
                if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
                        atombios_yuv_setup(encoder, true);
@@ -1492,8 +1485,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
 
 static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
 {
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+       if (radeon_encoder->active_device &
+           (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
+               struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+               if (dig)
+                       dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
+       }
+
        radeon_atom_output_lock(encoder, true);
        radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+       /* this is needed for the pll/ss setup to work correctly in some cases */
+       atombios_set_encoder_crtc_source(encoder);
 }
 
 static void radeon_atom_encoder_commit(struct drm_encoder *encoder)