From f2c83671cccc42345bfc9b506365936bbb6b9ef0 Mon Sep 17 00:00:00 2001 From: Paulo Cesar Pereira de Andrade Date: Fri, 24 Oct 2008 17:55:02 -0200 Subject: Make Dualhead option functional. Slightly change clock selection code to start using 501 compatible values, before checking 502 values, if it is a 502. DPMS for the VGA/second output was being set with bits inverted, that is dpms-on was programmed as dpms-off and vice versa. This was one of the reasons of dual head not working. Corrected wrong vsync programming for the crt. Cut&paste/typo caused programming vsync with hsync values, and thus, never getting the crt to accept the mode being programmed. If adding: Option "Dualhead" "True" to xorg.conf, now you should be able to do things like: $ DISPLAY=:0.0 xrandr --output VGA --right-of LVDS $ DISPLAY=:0.0 xrandr --output VGA --below LVDS and so on. *Iff* there is some way to not have any limitations for video playback, this option should be made default or automatically configured. --- src/smi501_crtc.c | 15 ++++++++------- src/smi501_output.c | 28 +++++++++------------------- src/smi_501.c | 14 ++------------ 3 files changed, 19 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/smi501_crtc.c b/src/smi501_crtc.c index 07a96ed..589b088 100644 --- a/src/smi501_crtc.c +++ b/src/smi501_crtc.c @@ -59,7 +59,7 @@ SMI501_CrtcVideoInit_lcd(xf86CrtcPtr crtc) pitch = (((crtc->rotatedData? crtc->mode.HDisplay : pScrn->displayWidth) * pSmi->Bpp) + 15) & ~15; - width = crtc->mode.HDisplay * pSmi->Bpp; + width = ((crtc->mode.HDisplay * pSmi->Bpp) + 15) & ~ 15; /* >> 4 because of the "unused bits" that should be set to 0 */ mode->panel_fb_width.f.offset = pitch >> 4; @@ -91,7 +91,7 @@ SMI501_CrtcVideoInit_crt(xf86CrtcPtr crtc) pitch = (((crtc->rotatedData? crtc->mode.HDisplay : pScrn->displayWidth) * pSmi->Bpp) + 15) & ~15; - width = crtc->mode.HDisplay * pSmi->Bpp; + width = ((crtc->mode.HDisplay * pSmi->Bpp) + 15) & ~ 15; /* >> 4 because of the "unused bits" that should be set to 0 */ mode->crt_fb_width.f.offset = pitch >> 4; @@ -131,6 +131,7 @@ SMI501_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y) mode->crt_display_ctl.f.pixel = ((x * pSmi->Bpp) & 15) / pSmi->Bpp; WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value); mode->crt_fb_address.f.address = Base >> 4; + mode->crt_fb_address.f.mselect = 0; mode->crt_fb_address.f.pending = 1; WRITE_SCR(pSmi, CRT_FB_ADDRESS, mode->crt_fb_address.value); } @@ -225,7 +226,7 @@ SMI501_CrtcModeSet_lcd(xf86CrtcPtr crtc, mode->panel_htotal.f.total = xf86mode->HTotal - 1; mode->panel_htotal.f.end = xf86mode->HDisplay - 1; - mode->panel_hsync.f.start = xf86mode->HSyncStart; + mode->panel_hsync.f.start = xf86mode->HSyncStart - 1; mode->panel_hsync.f.width = xf86mode->HSyncEnd - xf86mode->HSyncStart; @@ -288,16 +289,16 @@ SMI501_CrtcModeSet_crt(xf86CrtcPtr crtc, mode->crt_htotal.f.total = xf86mode->HTotal - 1; mode->crt_htotal.f.end = xf86mode->HDisplay - 1; - mode->crt_hsync.f.start = xf86mode->HSyncStart; + mode->crt_hsync.f.start = xf86mode->HSyncStart - 1; mode->crt_hsync.f.width = xf86mode->HSyncEnd - xf86mode->HSyncStart; mode->crt_vtotal.f.total = xf86mode->VTotal - 1; mode->crt_vtotal.f.end = xf86mode->VDisplay - 1; - mode->crt_vsync.f.start = xf86mode->HSyncStart; - mode->crt_vsync.f.height = xf86mode->HSyncEnd - - xf86mode->HSyncStart; + mode->crt_vsync.f.start = xf86mode->VSyncStart; + mode->crt_vsync.f.height = xf86mode->VSyncEnd - + xf86mode->VSyncStart; SMI501_WriteMode_crt(pScrn,mode); SMI501_CrtcAdjustFrame(crtc, x, y); diff --git a/src/smi501_output.c b/src/smi501_output.c index 8bd3db9..7a22955 100644 --- a/src/smi501_output.c +++ b/src/smi501_output.c @@ -38,16 +38,6 @@ authorization from The XFree86 Project or Silicon Motion. static void SMI501_OutputDPMS_lcd(xf86OutputPtr output, int dpms) -{ - ENTER(); - - /* Nothing - FIXME */ - - LEAVE(); -} - -static void -SMI501_OutputDPMS_panel(xf86OutputPtr output, int dpms) { ScrnInfoPtr pScrn = output->scrn; SMIPtr pSmi = SMIPTR(pScrn); @@ -71,7 +61,7 @@ SMI501_OutputDPMS_panel(xf86OutputPtr output, int dpms) LEAVE(); } -static void +void SMI501_OutputDPMS_crt(xf86OutputPtr output, int dpms) { ScrnInfoPtr pScrn = output->scrn; @@ -83,20 +73,20 @@ SMI501_OutputDPMS_crt(xf86OutputPtr output, int dpms) mode->system_ctl.value = READ_SCR(pSmi, SYSTEM_CTL); switch (dpms) { case DPMSModeOn: - mode->system_ctl.f.dpmsh = 1; - mode->system_ctl.f.dpmsv = 1; - break; - case DPMSModeStandby: mode->system_ctl.f.dpmsh = 0; - mode->system_ctl.f.dpmsv = 1; + mode->system_ctl.f.dpmsv = 0; break; - case DPMSModeSuspend: + case DPMSModeStandby: mode->system_ctl.f.dpmsh = 1; mode->system_ctl.f.dpmsv = 0; break; - case DPMSModeOff: + case DPMSModeSuspend: mode->system_ctl.f.dpmsh = 0; - mode->system_ctl.f.dpmsv = 0; + mode->system_ctl.f.dpmsv = 1; + break; + case DPMSModeOff: + mode->system_ctl.f.dpmsh = 1; + mode->system_ctl.f.dpmsv = 1; break; } WRITE_SCR(pSmi, SYSTEM_CTL, mode->system_ctl.value); diff --git a/src/smi_501.c b/src/smi_501.c index 80f3401..555dfd8 100644 --- a/src/smi_501.c +++ b/src/smi_501.c @@ -331,19 +331,9 @@ SMI501_WriteMode_crt(ScrnInfoPtr pScrn, MSOCRegPtr mode) void SMI501_WriteMode(ScrnInfoPtr pScrn, MSOCRegPtr restore) { - /* FIXME There is a problem here: - * The kernel may not have modified some values, like clocks, - * but when "restoring" them, it will actually change from a - * a valid value, to a random value. - */ -#if 0 - SMIPtr pSmi = SMIPTR(pScrn); - SMI501_WriteMode_common(pScrn, restore); SMI501_WriteMode_lcd(pScrn, restore); - if (pSmi->Dualhead) - SMI501_WriteMode_crt(pScrn, restore); -#endif + SMI501_WriteMode_crt(pScrn, restore); } void @@ -423,7 +413,7 @@ SMI501_FindClock(double clock, int32_t max_divider, Bool has1xclck, for (divider = 1; divider <= max_divider; divider += 2) { for (shift = 0; shift < 8; shift++) { /* Divider 1 not in specs form cards older then 502 */ - for (xclck = has1xclck != FALSE; xclck <= 1; xclck++) { + for (xclck = 1; xclck >= !has1xclck; xclck--) { diff = (mclk / (divider << shift << xclck)) - clock; if (fabs(diff) < best) { *x2_shift = shift; -- cgit v1.2.3