diff --git a/src/i830.h b/src/i830.h index 1319c6a..6144f9e 100644 --- a/src/i830.h +++ b/src/i830.h @@ -290,6 +290,7 @@ typedef struct _I830OutputPrivateRec { Bool load_detect_temp; int pipe_mask; int clone_mask; + u32 lvds_bits; /** Output-private structure. Should replace i2c_drv */ void *dev_priv; } I830OutputPrivateRec, *I830OutputPrivatePtr; diff --git a/src/i830_display.c b/src/i830_display.c index 6a2d1d7..4f3f8ef 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -1059,6 +1059,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + I830OutputPrivatePtr intel_output; int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; int fp_reg = (pipe == 0) ? FPA0 : FPB0; @@ -1088,7 +1089,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, */ for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; - I830OutputPrivatePtr intel_output = output->driver_private; + intel_output = output->driver_private; if (output->crtc != crtc) continue; @@ -1302,6 +1303,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, lvds |= LVDS_DITHER_ENABLE; } + lvds |= intel_output->lvds_bits; + OUTREG(LVDS, lvds); POSTING_READ(LVDS); } diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 33b4f26..a7fb8d9 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -542,23 +542,22 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, adjusted_mode->Clock = dev_priv->panel_fixed_mode->Clock; xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); + /* Make sure pre-965s set dither correctly */ + if (!IS_I965G(pI830) && dev_priv->panel_wants_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + /* Native modes don't need fitting */ if (adjusted_mode->HDisplay == mode->HDisplay && adjusted_mode->VDisplay == mode->VDisplay) { - pfit_control = 0; pfit_pgm_ratios = 0; border = 0; goto out; } - /* Basic panel fitting options */ - if (!IS_I965G(pI830)) { - if (dev_priv->panel_wants_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - } else { + /* 965+ wants fuzzy fitting */ + if (IS_I965G(pI830)) pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | PFIT_FILTER_FUZZY; - } /* * Deal with panel fitting options. Figure out how to stretch the image @@ -736,21 +735,15 @@ i830_lvds_prepare(xf86OutputPtr output) { I830OutputPrivatePtr intel_output = output->driver_private; struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t lvds; - - lvds = INREG(LVDS); - i830_lvds_dpms(output, DPMSModeOff); /* - * ->prepare will be called after the CRTC is off but before - * we set the mode, so program the PFIT regs here. + * The CRTC code (i830_display.c) actually enables LVDS, so + * set the bits it needs here. */ if (dev_priv->need_border) - OUTREG(LVDS, lvds | LVDS_BORDER_ENABLE); + intel_output->lvds_bits |= LVDS_BORDER_ENABLE; else - OUTREG(LVDS, lvds & (~LVDS_BORDER_ENABLE)); + intel_output->lvds_bits &= ~LVDS_BORDER_ENABLE; } static void @@ -767,8 +760,6 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode, */ OUTREG(PFIT_PGM_RATIOS, dev_priv->pfit_pgm_ratios); OUTREG(PFIT_CONTROL, dev_priv->pfit_control); - /* It's harmless to turn on the LVDS if it's already on */ - i830_lvds_dpms(output, DPMSModeOn); } /**