summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-24 17:55:02 -0200
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-24 17:55:02 -0200
commitf2c83671cccc42345bfc9b506365936bbb6b9ef0 (patch)
tree07e6bf7e71c5aa909201ee75bee483451763439b /src
parent1efe36ed5cf5b0931daa915ca3ce231b78168d87 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/smi501_crtc.c15
-rw-r--r--src/smi501_output.c28
-rw-r--r--src/smi_501.c14
3 files changed, 19 insertions, 38 deletions
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
@@ -39,16 +39,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);
MSOCRegPtr mode = pSmi->mode;
@@ -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;