diff options
-rw-r--r-- | src/smi_video.c | 12 | ||||
-rw-r--r-- | src/smilynx_crtc.c | 112 | ||||
-rw-r--r-- | src/smilynx_hw.c | 8 | ||||
-rw-r--r-- | src/smilynx_output.c | 36 |
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; } } |