--- src/i830_lvds.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 8 deletions(-) Index: xf86_video_intel/src/i830_lvds.c =================================================================== --- xf86_video_intel.orig/src/i830_lvds.c 2009-06-10 16:07:42.000000000 +0800 +++ xf86_video_intel/src/i830_lvds.c 2009-06-11 14:55:49.000000000 +0800 @@ -608,6 +608,8 @@ int left_border = 0, right_border = 0, top_border = 0, bottom_border = 0; int i; Bool border = 0; + uint32_t hsync_width, vsync_width, hblank_width, vblank_width; + uint32_t hsync_pos, vsync_pos; for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr other_output = xf86_config->output[i]; @@ -645,6 +647,10 @@ adjusted_mode->VTotal = pI830->lvds_fixed_mode->VTotal; adjusted_mode->Clock = pI830->lvds_fixed_mode->Clock; xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); + hsync_width = adjusted_mode->HSyncEnd - adjusted_mode->HSyncStart; + vsync_width = adjusted_mode->VSyncEnd - adjusted_mode->VSyncStart; + hblank_width = adjusted_mode->CrtcHBlankEnd - adjusted_mode->CrtcHBlankStart; + vblank_width = adjusted_mode->CrtcVBlankEnd - adjusted_mode->CrtcVBlankStart; /* Make sure pre-965s set dither correctly */ if (!IS_I965G(pI830) && pI830->lvds_dither) @@ -680,6 +686,11 @@ /* Change the value here to see the borders for debugging */ OUTREG(BCLRPAT_A, 0); OUTREG(BCLRPAT_B, 0); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "origin : hsync width = %d, hblank width %d" + "vsync width = %d, vblank width %d\n", + hsync_width, hblank_width, vsync_width, vblank_width); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "target mode : h %d, v %d\n", + mode->HDisplay, mode->VDisplay); switch (dev_priv->fitting_mode) { case CENTER: /* @@ -703,14 +714,43 @@ adjusted_mode->CrtcHBlankStart = mode->HDisplay + right_border - 1; adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHTotal - left_border - 1; - adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart; - adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHBlankEnd; + adjusted_mode->CrtcHBlankStart += 1; + adjusted_mode->CrtcHBlankStart &= ~(0x01); + adjusted_mode->CrtcHBlankEnd = (adjusted_mode->CrtcHBlankEnd + 1) & ~(0x01); + /* make the hblank start/end be a multiple of two */ + /* don't change the hlank widht */ + hblank_width = adjusted_mode->CrtcHBlankEnd - adjusted_mode->CrtcHBlankStart; + hsync_pos = (hblank_width - hsync_width ) / 2; + if (hsync_pos % 2) + hsync_pos++; + adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart + hsync_pos; + adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + hsync_width; + /* Don't change the hsync width */ adjusted_mode->CrtcVDisplay = mode->VDisplay; adjusted_mode->CrtcVBlankStart = mode->VDisplay + bottom_border - 1; adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVTotal - top_border - 1; - adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart; - adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVBlankEnd; + adjusted_mode->CrtcVBlankStart += 1; + adjusted_mode->CrtcVBlankStart &= ~(0x01); + adjusted_mode->CrtcVBlankEnd = (adjusted_mode->CrtcVBlankEnd + 1) & ~(0x01); + vblank_width = adjusted_mode->CrtcVBlankEnd - adjusted_mode->CrtcVBlankStart; + /* make the vblank start/end be a multiple of two */ + /* Don't change the vblank width */ + vsync_pos = (vblank_width - vsync_width ) / 2; + if (vsync_pos % 2) + vsync_pos++; + adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart + vsync_pos; + adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + vsync_width; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "center mode : hsync width = %d, hblank width %d" + "vsync width = %d, vblank width %d\n", + hsync_width, hblank_width, vsync_width, vblank_width); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Center mode : adjusted_mode: h (%d, %d, %d) " + "v(%d, %d, %d)\n", + adjusted_mode->CrtcHDisplay, adjusted_mode->CrtcHBlankStart, + adjusted_mode->CrtcHSyncStart, adjusted_mode->CrtcVDisplay, + adjusted_mode->CrtcVBlankStart, adjusted_mode->CrtcVSyncStart); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "test end\n"); + /* Don't change the vsync width */ border = 1; break; case FULL_ASPECT: @@ -763,8 +803,25 @@ right_border - 1; adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHTotal - left_border - 1; - adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart; - adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHBlankEnd; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, " hblank before modification: start %d, end %d\n", + adjusted_mode->CrtcHBlankStart, adjusted_mode->CrtcHBlankEnd); + adjusted_mode->CrtcHBlankEnd = (adjusted_mode->CrtcHBlankEnd + 1) + & ~(0x01); + adjusted_mode->CrtcHBlankStart = (adjusted_mode->CrtcHBlankStart + 1) & ~(0x01); + /* make the hblank start/end be a multiple of two */ + hblank_width = adjusted_mode->CrtcHBlankEnd - adjusted_mode->CrtcHBlankStart; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, " hblank after modification: start %d, end %d, width =%d\n", + adjusted_mode->CrtcHBlankStart, adjusted_mode->CrtcHBlankEnd, hblank_width); + hsync_pos = (hblank_width - hsync_width ) / 2; + if (hsync_pos % 2) + hsync_pos++; + adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart + hsync_pos; + adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + hsync_width; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, " Full aspect(horizontal change) " + "active %d, blank %d, sync %d\n", + adjusted_mode->CrtcHDisplay, adjusted_mode->CrtcHBlankStart, + adjusted_mode->CrtcHSyncStart); + /* don't change the Hsync width*/ border = 1; } else if (panel_ratio < desired_ratio) { /* Letter */ unsigned long scaled_height = (float)mode->VDisplay * @@ -786,8 +843,26 @@ bottom_border - 1; adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVTotal - top_border - 1; - adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart; - adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVBlankEnd; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, " vblank before modification: start %d, end %d\n", + adjusted_mode->CrtcVBlankStart, adjusted_mode->CrtcVBlankEnd); + adjusted_mode->CrtcVBlankEnd = (adjusted_mode->CrtcVBlankEnd + 1) & + ~(0x01); + adjusted_mode->CrtcVBlankStart = (adjusted_mode->CrtcVBlankStart + 1) & + ~(0x01); + /* make the vblank start/end be a multiple of two */ + vblank_width = adjusted_mode->CrtcVBlankEnd - adjusted_mode->CrtcVBlankStart; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, " vblank after modification: start %d, end %d, width =%d\n", + adjusted_mode->CrtcVBlankStart, adjusted_mode->CrtcVBlankEnd, vblank_width); + vsync_pos = (vblank_width - vsync_width ) / 2; + if (vsync_pos % 2) + vsync_pos++; + adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart + vsync_pos; + adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + vsync_width; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, " Full aspect(vertical change) " + "active %d, blank %d, sync %d\n", + adjusted_mode->CrtcVDisplay, adjusted_mode->CrtcVBlankStart, + adjusted_mode->CrtcVSyncStart); + /* don't change the Vsync width */ border = 1; } else { /* Aspects match, let hw scale both directions */ pfit_control |= VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | @@ -801,6 +876,8 @@ PFIT_VERT_SCALE_MASK) | ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) & PFIT_HORIZ_SCALE_MASK)); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "pfit=%d, pfit_ratio=%d\n", + pfit_control, pfit_pgm_ratios); } break; case FULL: