summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/smi_video.c12
-rw-r--r--src/smilynx_crtc.c112
-rw-r--r--src/smilynx_hw.c8
-rw-r--r--src/smilynx_output.c36
4 files changed, 97 insertions, 71 deletions
diff --git a/src/smi_video.c b/src/smi_video.c
index 3ae30f4..9bf0e1b 100644
--- a/src/smi_video.c
+++ b/src/smi_video.c
@@ -1057,10 +1057,10 @@ SMI_PutVideo(
dstBox.x2 = drw_x + drw_w;
dstBox.y2 = drw_y + drw_h;
- if(!xf86_crtc_clip_video_helper(pScrn, &crtc, NULL, &dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
+ if(!xf86_crtc_clip_video_helper(pScrn, &crtc, crtcConf->crtc[0], &dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
LEAVE(Success);
- if(pSmi->Dualhead && crtc == crtcConf->crtc[0])
+ if(pSmi->Dualhead && crtc == crtcConf->crtc[1])
LEAVE(Success);
/* Transform dstBox to the CRTC coordinates */
@@ -1516,7 +1516,7 @@ SMI_PutImage(
LEAVE(Success);
}
else {
- if (!xf86_crtc_clip_video_helper(pScrn, &crtc, NULL, &dstBox,
+ if (!xf86_crtc_clip_video_helper(pScrn, &crtc, crtcConf->crtc[0], &dstBox,
&x1, &x2, &y1, &y2, clipBoxes,
width, height))
LEAVE(Success);
@@ -1629,7 +1629,7 @@ SMI_PutImage(
drw_w, drw_h);
}
else{
- if(!pSmi->Dualhead || crtc == crtcConf->crtc[1])
+ if(crtc == crtcConf->crtc[0])
SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2,
&dstBox, src_w, src_h, drw_w, drw_h);
}
@@ -2461,7 +2461,7 @@ SMI_DisplaySurface(
dstBox.y1 = drw_y;
dstBox.y2 = drw_y + drw_h;
- if(!xf86_crtc_clip_video_helper(surface->pScrn, &crtc, NULL, &dstBox,
+ if(!xf86_crtc_clip_video_helper(surface->pScrn, &crtc, crtcConf->crtc[0], &dstBox,
&x1, &x2, &y1, &y2, clipBoxes, surface->width, surface->height))
LEAVE(Success);
@@ -2485,7 +2485,7 @@ SMI_DisplaySurface(
surface->height, surface->pitches[0], x1, y1,
x2, y2, &dstBox, vid_w, vid_h, drw_w, drw_h);
else{
- if(!pSmi->Dualhead || crtc == crtcConf->crtc[1])
+ if(crtc == crtcConf->crtc[0])
SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0],
surface->width, surface->height, surface->pitches[0], x1, y1, x2,
y2, &dstBox, vid_w, vid_h, drw_w, drw_h);
diff --git a/src/smilynx_crtc.c b/src/smilynx_crtc.c
index e5963ff..72e0db2 100644
--- a/src/smilynx_crtc.c
+++ b/src/smilynx_crtc.c
@@ -194,7 +194,7 @@ SMILynx_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y)
WRITE_VPR(pSmi, 0x0C, Base);
WRITE_FPR(pSmi, FPR0C, Base);
}else{
- if(pSmi->Dualhead && crtc == crtcConf->crtc[0]){
+ if(pSmi->Dualhead && crtc == crtcConf->crtc[1]){
/* LCD */
/* FIFO1 read start address */
@@ -857,6 +857,7 @@ SMILynx_CrtcDPMS_crt(xf86CrtcPtr crtc, int mode)
ScrnInfoPtr pScrn = crtc->scrn;
SMIPtr pSmi = SMIPTR(pScrn);
SMIRegPtr reg = pSmi->mode;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
ENTER();
@@ -867,6 +868,39 @@ SMILynx_CrtcDPMS_crt(xf86CrtcPtr crtc, int mode)
VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, reg->SR21);
+ /* Wait for vertical retrace */
+ while (hwp->readST01(hwp) & 0x8) ;
+ while (!(hwp->readST01(hwp) & 0x8)) ;
+
+ if(mode == DPMSModeOn){
+ /* Reload the LUT */
+ SMILynx_CrtcLoadLUT_crt(crtc);
+ }
+
+ LEAVE();
+}
+
+static void
+SMILynx_CrtcDPMS_lcd(xf86CrtcPtr crtc, int mode)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ SMIPtr pSmi = SMIPTR(pScrn);
+ SMIRegPtr reg = pSmi->mode;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ ENTER();
+
+ if(mode == DPMSModeOff)
+ reg->SR31 &= ~0x80; /* Disable Virtual Refresh */
+ else
+ reg->SR31 |= 0x80; /* Enable Virtual Refresh */
+
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, reg->SR31);
+
+ /* Wait for vertical retrace */
+ while (hwp->readST01(hwp) & 0x8) ;
+ while (!(hwp->readST01(hwp) & 0x8)) ;
+
LEAVE();
}
@@ -912,56 +946,52 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn)
LEAVE(FALSE);
crtc->driver_private = crtcPriv;
}else{
- if(pSmi->Dualhead){
- /* CRTC is LCD*/
- SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
- crtcFuncs->mode_set = SMILynx_CrtcModeSet_lcd;
- crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup;
- crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
- crtcPriv->video_init = SMILynx_CrtcVideoInit_lcd;
- crtcPriv->load_lut = SMILynx_CrtcLoadLUT_lcd;
-
- if(! (crtc = xf86CrtcCreate(pScrn,crtcFuncs)))
- LEAVE(FALSE);
- crtc->driver_private = crtcPriv;
+ /* CRTC0 can drive both outputs when virtual refresh is
+ disabled, and only the VGA output with virtual refresh
+ enabled. */
+ SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
- /* CRTC1 is CRT */
- SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
+ if(pSmi->useBIOS){
+ crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios;
+ }else{
crtcFuncs->dpms = SMILynx_CrtcDPMS_crt;
- crtcFuncs->mode_set = SMILynx_CrtcModeSet_crt;
- crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup;
- crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
- crtcPriv->video_init = SMILynx_CrtcVideoInit_crt;
- crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt;
- if(! (crtc = xf86CrtcCreate(pScrn,crtcFuncs)))
- LEAVE(FALSE);
- crtc->driver_private = crtcPriv;
+ if(pSmi->Dualhead){
+ /* The standard VGA CRTC registers get locked in
+ virtual refresh mode. */
+ crtcFuncs->mode_set = SMILynx_CrtcModeSet_crt;
- }else{
- /* CRTC0 is LCD, but in standard refresh mode
- it is controlled through the primary VGA registers */
- SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
-
- if(pSmi->useBIOS){
- crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios;
}else{
- crtcFuncs->dpms = SMILynx_CrtcDPMS_crt;
crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga;
}
+ }
+
+ crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup;
+ crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
+ crtcPriv->video_init = SMILynx_CrtcVideoInit_crt;
+ crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt;
+
+ if(pSmi->HwCursor){
+ crtcFuncs->set_cursor_colors = SMILynx_CrtcSetCursorColors_crt;
+ crtcFuncs->set_cursor_position = SMILynx_CrtcSetCursorPosition_crt;
+ crtcFuncs->show_cursor = SMILynx_CrtcShowCursor_crt;
+ crtcFuncs->hide_cursor = SMILynx_CrtcHideCursor_crt;
+ crtcFuncs->load_cursor_image = SMILynx_CrtcLoadCursorImage_crt;
+ }
+ if(! (crtc = xf86CrtcCreate(pScrn,crtcFuncs)))
+ LEAVE(FALSE);
+ crtc->driver_private = crtcPriv;
+
+ if(pSmi->Dualhead){
+ /* CRTC1 drives LCD when enabled. */
+ SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
+ crtcFuncs->mode_set = SMILynx_CrtcModeSet_lcd;
crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup;
+ crtcFuncs->dpms = SMILynx_CrtcDPMS_lcd;
crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
- crtcPriv->video_init = SMILynx_CrtcVideoInit_crt;
- crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt;
-
- if(pSmi->HwCursor){
- crtcFuncs->set_cursor_colors = SMILynx_CrtcSetCursorColors_crt;
- crtcFuncs->set_cursor_position = SMILynx_CrtcSetCursorPosition_crt;
- crtcFuncs->show_cursor = SMILynx_CrtcShowCursor_crt;
- crtcFuncs->hide_cursor = SMILynx_CrtcHideCursor_crt;
- crtcFuncs->load_cursor_image = SMILynx_CrtcLoadCursorImage_crt;
- }
+ crtcPriv->video_init = SMILynx_CrtcVideoInit_lcd;
+ crtcPriv->load_lut = SMILynx_CrtcLoadLUT_lcd;
if(! (crtc = xf86CrtcCreate(pScrn,crtcFuncs)))
LEAVE(FALSE);
diff --git a/src/smilynx_hw.c b/src/smilynx_hw.c
index 8d2c523..158e20f 100644
--- a/src/smilynx_hw.c
+++ b/src/smilynx_hw.c
@@ -87,12 +87,8 @@ SMILynx_HWInit(ScrnInfoPtr pScrn)
/* Select no displays */
mode->SR31 &= ~0x07;
- /* Enable virtual refresh */
- if(pSmi->Dualhead){
- mode->SR31 |= 0x80;
- }else{
- mode->SR31 &= ~0x80;
- }
+ /* Disable virtual refresh */
+ mode->SR31 &= ~0x80;
/* Disable expansion */
mode->SR32 &= ~0x03;
diff --git a/src/smilynx_output.c b/src/smilynx_output.c
index aba6db5..fefa8c5 100644
--- a/src/smilynx_output.c
+++ b/src/smilynx_output.c
@@ -82,17 +82,25 @@ SMILynx_OutputDPMS_lcd(xf86OutputPtr output, int mode)
ScrnInfoPtr pScrn = output->scrn;
SMIPtr pSmi = SMIPTR(pScrn);
SMIRegPtr reg = pSmi->mode;
+ xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn);
ENTER();
switch (mode) {
case DPMSModeOn:
- if(pSmi->lcd == 2 /* LCD is DSTN */
- || pSmi->Dualhead /* Virtual Refresh is enabled */)
+ if(pSmi->Dualhead &&
+ output->crtc == crtcConf->crtc[1]){
+ /* Virtual Refresh is enabled */
+
reg->SR21 &= ~0x10; /* Enable LCD framebuffer read operation and DSTN dithering engine */
- if(pSmi->lcd == 2 /* LCD is DSTN */
- && !pSmi->Dualhead /* Virtual Refresh is disabled */)
- reg->SR21 &= ~0x20; /* Enable LCD framebuffer write operation */
+ }else{
+ if(pSmi->lcd == 2){
+ /* LCD is DSTN */
+
+ reg->SR21 &= ~0x10; /* Enable LCD framebuffer read operation and DSTN dithering engine */
+ reg->SR21 &= ~0x20; /* Enable LCD framebuffer write operation */
+ }
+ }
reg->SR31 |= 0x01; /* Enable LCD display*/
break;
@@ -269,13 +277,10 @@ SMILynx_OutputPreInit(ScrnInfoPtr pScrn)
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
- output->possible_crtcs = 1 << 0;
- if(pSmi->Dualhead)
- output->possible_clones = 0;
- else
- output->possible_clones = 1 << 1;
+ output->possible_crtcs = (1 << 0) | (1 << 1);
+ output->possible_clones = 1 << 1;
- if(!pSmi->useBIOS){
+ if(pSmi->Dualhead){
/* Output 1 is CRT */
SMI_OutputFuncsInit_base(&outputFuncs);
outputFuncs->dpms = SMILynx_OutputDPMS_crt;
@@ -288,13 +293,8 @@ SMILynx_OutputPreInit(ScrnInfoPtr pScrn)
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
- if(pSmi->Dualhead){
- output->possible_crtcs = 1 << 1;
- output->possible_clones = 0;
- }else{
- output->possible_crtcs = 1 << 0;
- output->possible_clones = 1 << 0;
- }
+ output->possible_crtcs = 1 << 0;
+ output->possible_clones = 1 << 0;
}
}