.gitignore | 3 ChangeLog | 68 Makefile.am | 11 configure.ac | 17 man/.cvsignore | 2 man/siliconmotion.man | 133 - src/.cvsignore | 6 src/Makefile.am | 16 src/regsmi.h | 166 +- src/smi.h | 305 ++-- src/smi501_crtc.c | 678 +++++++++ src/smi501_output.c | 173 ++ src/smi_501.c | 662 +++++++++ src/smi_501.h | 1479 +++++++++++++++++++++ src/smi_accel.c | 152 +- src/smi_crtc.c | 278 ++++ src/smi_crtc.h | 65 src/smi_dac.c | 19 src/smi_dga.c | 284 ---- src/smi_driver.c | 3403 ++++++++++++++++---------------------------------- src/smi_exa.c | 455 ++++-- src/smi_hwcurs.c | 403 ----- src/smi_i2c.c | 27 src/smi_output.c | 192 ++ src/smi_pcirename.h | 6 src/smi_shadow.c | 354 ----- src/smi_video.c | 1127 ++++++++-------- src/smi_xaa.c | 406 ++--- src/smilynx.h | 41 src/smilynx_crtc.c | 974 ++++++++++++++ src/smilynx_hw.c | 658 +++++++++ src/smilynx_output.c | 303 ++++ 32 files changed, 8171 insertions(+), 4695 deletions(-)
New commits: commit fdc2c50682b240e5966e4e5a7b45552ee2043bfc Author: Paulo Cesar Pereira de Andrade <[email protected]> Date: Mon Dec 29 18:41:05 2008 -0200 Bump release to 1.7.0. This driver supports smi 50x chipsets, randr 1.2, exa, dual head, etc. Special thanks to Teddy Wang <teddy.wang AT siliconmotion.com.cn> for support and help in responding and/or triaging hardware related questions. diff --git a/configure.ac b/configure.ac index 99690c5..5ec0679 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-siliconmotion], - 1.6.1, + 1.7.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-siliconmotion) commit 97eb5da1040ca7882e60b86ffaf25b6c021a3df5 Author: Paulo Cesar Pereira de Andrade <[email protected]> Date: Mon Dec 29 18:39:54 2008 -0200 Use util-macros XORG_CHANGELOG and XORG_CWARNFLAGS. Also correct only compilation warning about possibly uninitialized variable. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 46bee4b..0000000 --- a/ChangeLog +++ /dev/null @@ -1,68 +0,0 @@ -2006-04-07 Adam Jackson <[email protected]> - - * configure.ac: - * src/smi_driver.c: - Bump to 1.4.1 for Xv changes. - -2006-04-07 Aaron Plattner <[email protected]> - - * src/smi_video.c: (SMI_PutVideo), (SMI_PutImage): - Add a DrawablePtr argument to the XV functions to pave the way for - redirected video. - -2006-04-07 Adam Jackson <[email protected]> - - * configure.ac: - * src/smi.h: - * src/smi_dga.c: - * src/smi_driver.c: - * src/smi_i2c.c: - * src/smi_shadow.c: - Unlibcwrap. Bump server version requirement. Bump to 1.4.0. - -2006-02-08 Luc Verhaegen <[email protected]> - - * src/smi.h: - * src/smi_driver.c: (SMI_PreInit), (SMI_ModeInit): - - Clean up insane pScrn->clock usage. - -2005-12-20 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version for X11R7 release. - -2005-12-14 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for final X11R7 release candidate. - -2005-12-06 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * man/Makefile.am: - Change *man_SOURCES ==> *man_PRE to fix autotools warnings. - -2005-12-03 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for X11R7 RC3 release. - -2005-12-01 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Remove extraneous AC_MSG_RESULT. - -2005-11-29 Adam Jackson <[email protected]> - - * configure.ac: - Only build dlloader modules by default. - -2005-11-09 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for X11R7 RC2 release. - -2005-11-01 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update pkgcheck dependencies to work with separate build roots. diff --git a/Makefile.am b/Makefile.am index 4934358..d79e354 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,4 +21,13 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = src man -EXTRA_DIST = CALLMAP Release.txt +EXTRA_DIST = ChangeLog CALLMAP Release.txt + +MAINTAINERCLEANFILES=ChangeLog + +.PHONY: ChangeLog + +ChangeLog: + $(CHANGELOG_CMD) + +dist-hook: ChangeLog diff --git a/configure.ac b/configure.ac index c157792..99690c5 100644 --- a/configure.ac +++ b/configure.ac @@ -26,6 +26,11 @@ AC_INIT([xf86-video-siliconmotion], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-siliconmotion) +# Require xorg-macros version 1.2 or newer for XORG_CWARNFLAGS and +# XORG_CHANGELOG macros +m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.2.1 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.2.1) + AC_CONFIG_SRCDIR([Makefile.am]) AM_CONFIG_HEADER([config.h]) AC_CONFIG_AUX_DIR(.) @@ -81,6 +86,8 @@ if test "x$XMODES" = xyes; then AC_DEFINE(HAVE_XMODES, 1, [X server has new mode code]) fi +XORG_CWARNFLAGS +XORG_CFLAGS="$CWARNFLAGS $XORG_CFLAGS" AC_SUBST([XORG_CFLAGS]) AC_SUBST([moduledir]) @@ -89,6 +96,7 @@ AC_SUBST([DRIVER_NAME]) XORG_MANPAGE_SECTIONS XORG_RELEASE_VERSION +XORG_CHANGELOG AC_OUTPUT([ Makefile diff --git a/src/smi_driver.c b/src/smi_driver.c index 12b618f..28cecf3 100644 --- a/src/smi_driver.c +++ b/src/smi_driver.c @@ -1247,10 +1247,8 @@ SMI_DetectMCLK(ScrnInfoPtr pScrn) if (IS_MSOC(pSmi)) { clock.value = READ_SCR(pSmi, CURRENT_CLOCK); if (xf86GetOptValFreq(pSmi->Options, OPTION_MXCLK, - OPTUNITS_MHZ, &real)) { + OPTUNITS_MHZ, &real)) pSmi->MXCLK = (int)(real * 1000.0); - mxclk = pSmi->MXCLK; - } } /* Already programmed MCLK */ @@ -1282,10 +1280,13 @@ SMI_DetectMCLK(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MCLK = %1.3f\n", mclk / 1000.0); if (IS_MSOC(pSmi)) { - if (pSmi->MXCLK == 0) + if (pSmi->MXCLK == 0) { mxclk = ((clock.f.m1_select ? 336 : 288) / ((clock.f.m1_divider ? 3 : 1) << (unsigned)clock.f.m1_shift)) * 1000; + } + else + mxclk = pSmi->MXCLK; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MXCLK = %1.3f\n", mxclk / 1000.0); } } commit deb2f845dd370ba819d02cb21b8a481827497af6 Author: Paulo Cesar Pereira de Andrade <[email protected]> Date: Mon Dec 29 18:35:22 2008 -0200 Simplification and redundancy removal in video code. FOURCC_YV12 and FOURCC_I420 handling also was buggy. First it was doing a noop by swapping offset2 and offset3 values twice, and second, swap is not required when using smi 501/502 CSC video. Changed SMI_DisplayVideo0501_CSC() to not set static values to registers in a possible loop, if there is clipping. diff --git a/src/smi_video.c b/src/smi_video.c index 18cb0c2..3ae30f4 100644 --- a/src/smi_video.c +++ b/src/smi_video.c @@ -1530,6 +1530,7 @@ SMI_PutImage( switch (id) { case FOURCC_YV12: + case FOURCC_I420: srcPitch = (width + 3) & ~3; offset2 = srcPitch * height; srcPitch2 = ((width >> 1) + 3) & ~3; @@ -1539,16 +1540,6 @@ SMI_PutImage( else dstPitch = ((width << 1) + 15) & ~15; break; - case FOURCC_I420: - srcPitch = (width + 3) & ~3; - offset3 = srcPitch * height; - srcPitch2 = ((width >> 1) + 3) & ~3; - offset2 = offset3 + (srcPitch2 * (height >> 1)); - if (pSmi->CSCVideo) - dstPitch = (((width >> 1) + 15) & ~15) << 1; - else - dstPitch = ((width << 1) + 15) & ~15; - break; case FOURCC_RV24: bpp = 3; srcPitch = width * bpp; @@ -1589,19 +1580,17 @@ SMI_PutImage( tmp = ((top >> 1) * srcPitch2) + (left >> 2); offset2 += tmp; offset3 += tmp; - - if (id == FOURCC_I420) { - tmp = offset2; - offset2 = offset3; - offset3 = tmp; - } - if (pSmi->CSCVideo) CopyYV12ToVideoMem(buf, buf + offset2, buf + offset3, dstStart, srcPitch, srcPitch2, dstPitch, height, width); else { + if (id == FOURCC_I420) { + tmp = offset2; + offset2 = offset3; + offset3 = tmp; + } nLines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), buf + offset2, buf + offset3, dstStart, @@ -1849,8 +1838,39 @@ SMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset, csc = (1 << 31) | (1 << 25); if (pSmi->Bpp > 2) csc |= 1 << 26; - if (id == FOURCC_YV12 || id == FOURCC_I420) - csc |= 2 << 28; + + switch (id) { + case FOURCC_YV12: + SrcUVPitch = SrcYPitch / 2; + SrcVBase = SrcYBase + SrcYPitch * height; + SrcUBase = SrcVBase + SrcUVPitch * height / 2; + csc |= 2 << 28; + break; + + case FOURCC_I420: + SrcUVPitch = SrcYPitch / 2; + SrcUBase = SrcYBase + SrcYPitch * height; + SrcVBase = SrcUBase + SrcUVPitch * height / 2; + csc |= 2 << 28; + break; + + case FOURCC_YUY2: + case FOURCC_RV16: + case FOURCC_RV32: + SrcUBase = SrcVBase = SrcYBase; + SrcUVPitch = SrcYPitch; + break; + + default: + LEAVE(); + } + + WRITE_DPR(pSmi, 0xE4, ((SrcYPitch >> 4) << 16) | (SrcUVPitch >> 4)); + WRITE_DPR(pSmi, 0xC8, SrcYBase); + WRITE_DPR(pSmi, 0xD8, SrcUBase); + WRITE_DPR(pSmi, 0xDC, SrcVBase); + WRITE_DPR(pSmi, 0xF4, (((ScaleXn << 13) | ScaleXd) << 16) | + (ScaleYn << 13 | ScaleYd)); for (i = 0; i < nbox; i++, pbox++) { rect_x = pbox->x1; @@ -1858,30 +1878,6 @@ SMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset, rect_w = pbox->x2 - pbox->x1; rect_h = pbox->y2 - pbox->y1; - switch (id) { - case FOURCC_YV12: - SrcUVPitch = SrcYPitch / 2; - SrcVBase = SrcYBase + SrcYPitch * height; - SrcUBase = SrcVBase + SrcUVPitch * height / 2; - break; - - case FOURCC_I420: - SrcUVPitch = SrcYPitch / 2; - SrcUBase = SrcYBase + SrcYPitch * height; - SrcVBase = SrcUBase + SrcUVPitch * height / 2; - break; - - case FOURCC_YUY2: - case FOURCC_RV16: - case FOURCC_RV32: - SrcUBase = SrcVBase = SrcYBase; - SrcUVPitch = SrcYPitch; - break; - - default: - return; - } - SrcLn = (rect_x - dstBox->x1) * Hscale; SrcLd = ((rect_x - dstBox->x1) << 13) * Hscale - (SrcLn << 13); SrcRn = (rect_x + rect_w - dstBox->x1) * Hscale; @@ -1896,15 +1892,9 @@ SMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset, WRITE_DPR(pSmi, 0xD0, (SrcLn << 16) | SrcLd); WRITE_DPR(pSmi, 0xD4, (SrcTn << 16) | SrcTd); WRITE_DPR(pSmi, 0xE0, (SrcDimX << 16) | SrcDimY); - WRITE_DPR(pSmi, 0xE4, ((SrcYPitch >> 4) << 16) | (SrcUVPitch >> 4)); WRITE_DPR(pSmi, 0xE8, (rect_x << 16) | rect_y); WRITE_DPR(pSmi, 0xEC, (rect_w << 16) | rect_h); WRITE_DPR(pSmi, 0xF0, ((DestPitch >> 4) << 16) | rect_h); - WRITE_DPR(pSmi, 0xF4, (((ScaleXn << 13) | ScaleXd) << 16) | - (ScaleYn << 13 | ScaleYd)); - WRITE_DPR(pSmi, 0xC8, SrcYBase); - WRITE_DPR(pSmi, 0xD8, SrcUBase); - WRITE_DPR(pSmi, 0xDC, SrcVBase); while (READ_DPR(pSmi, 0xfc) & (1 << 31)) ; commit 46741589529809c17aa1e9719492a4b623de6ddf Author: Francisco Jerez <[email protected]> Date: Sat Dec 27 00:52:05 2008 +0100 Some more quirks for the SM712. * Program the MCLK to 157MHz on startup. * Adjust the requested pixel clock if it's near one of the known stable frequencies. * Prefer the clock alternative with post scalar turned on when the denominator is even. diff --git a/src/smi_dac.c b/src/smi_dac.c index f72c77e..de4d794 100644 --- a/src/smi_dac.c +++ b/src/smi_dac.c @@ -92,9 +92,20 @@ SMI_CommonCalcClock(int scrnIndex, long freq, int min_m, int min_n1, best_m, best_n1, best_n2); if (SMI_LYNX_SERIES(pSmi->Chipset)) { - *ndiv = best_n1 | (best_n2 << 6); + /* Prefer post scalar enabled for even denominators */ + if (freq < 70000 && max_n2 > 0 && + best_n2 == 0 && best_n1 % 2 == 0){ + best_n1 >>= 1; + best_n2 = 1; + } + + *ndiv = best_n1 | + (best_n2 & 0x1) << 7 | + (best_n2 & 0x2) >> 1 <<6; } else { *ndiv = best_n1 | (best_n2 << 7); + + /* Enable second VCO */ if (freq > 120000) *ndiv |= 1 << 6; } diff --git a/src/smi_driver.c b/src/smi_driver.c index 79d8a0c..12b618f 100644 --- a/src/smi_driver.c +++ b/src/smi_driver.c @@ -1222,14 +1222,24 @@ SMI_DetectMCLK(ScrnInfoPtr pScrn) int mclk, mxclk; SMIPtr pSmi = SMIPTR(pScrn); - pSmi->MCLK = pSmi->MXCLK = 0; + /* MCLK defaults */ + if (pSmi->Chipset == SMI_LYNXEMplus){ + /* The SM712 can be safely clocked up to 157MHz, according to + Silicon Motion engineers. */ + pSmi->MCLK = 157000; + }else + pSmi->MCLK = 0; + + pSmi->MXCLK = 0; + + /* MCLK from user settings */ if (xf86GetOptValFreq(pSmi->Options, OPTION_MCLK, OPTUNITS_MHZ, &real)) { - pSmi->MCLK = (int)(real * 1000.0); - if (!IS_MSOC(pSmi) && pSmi->MCLK > 120000) { + if (IS_MSOC(pSmi) || (int)real <= 120) { + pSmi->MCLK = (int)(real * 1000.0); + } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Memory Clock %1.3f MHz larger than limit of 120 MHz\n", real); - pSmi->MCLK = 0; } } mclk = pSmi->MCLK; @@ -1243,6 +1253,7 @@ SMI_DetectMCLK(ScrnInfoPtr pScrn) } } + /* Already programmed MCLK */ if (pSmi->MCLK == 0) { if (IS_MSOC(pSmi)) mclk = ((clock.f.m_select ? 336 : 288) / diff --git a/src/smilynx_crtc.c b/src/smilynx_crtc.c index 508184f..e5963ff 100644 --- a/src/smilynx_crtc.c +++ b/src/smilynx_crtc.c @@ -227,6 +227,34 @@ SMILynx_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y) LEAVE(); } +static Bool +SMILynx_CrtcModeFixup(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + + ENTER(); + + if (pSmi->Chipset == SMI_LYNXEMplus) { + /* Adjust the pixel clock in case it is near one of the known + stable frequencies (KHz) */ + int stable_clocks[] = {46534,}; + int epsilon = 2000; + int i; + + for (i=0; i < sizeof(stable_clocks)/sizeof(int); i++) { + if ( abs(mode->Clock - stable_clocks[i]) < epsilon) { + adjusted_mode->Clock = stable_clocks[i]; + break; + } + } + } + + LEAVE(TRUE); +} + static void SMILynx_CrtcModeSet_vga(xf86CrtcPtr crtc, DisplayModePtr mode, @@ -254,13 +282,13 @@ SMILynx_CrtcModeSet_vga(xf86CrtcPtr crtc, /* calculate vclk1 */ if (SMI_LYNX_SERIES(pSmi->Chipset)) { - SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock, + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, 1, 1, 63, 0, 3, pSmi->clockRange.minClock, pSmi->clockRange.maxClock, ®->SR6C, ®->SR6D); } else { - SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock, + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, 1, 1, 63, 0, 1, pSmi->clockRange.minClock, pSmi->clockRange.maxClock, @@ -348,13 +376,13 @@ SMILynx_CrtcModeSet_crt(xf86CrtcPtr crtc, /* calculate vclk1 */ if (SMI_LYNX_SERIES(pSmi->Chipset)) { - SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock, + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, 1, 1, 63, 0, 3, pSmi->clockRange.minClock, pSmi->clockRange.maxClock, ®->SR6C, ®->SR6D); } else { - SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock, + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, 1, 1, 63, 0, 1, pSmi->clockRange.minClock, pSmi->clockRange.maxClock, @@ -456,19 +484,20 @@ SMILynx_CrtcModeSet_lcd(xf86CrtcPtr crtc, /* Program the PLL */ /* calculate vclk2 */ - if (pSmi->Chipset == SMI_LYNX3DM) { - SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock, - 1, 1, 63, 0, 1, + if (SMI_LYNX_SERIES(pSmi->Chipset)) { + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, + 1, 1, 63, 0, 0, pSmi->clockRange.minClock, pSmi->clockRange.maxClock, ®->SR6E, ®->SR6F); } else { - SMI_CommonCalcClock(pScrn->scrnIndex, mode->Clock, - 1, 1, 63, 0, 0, + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, + 1, 1, 63, 0, 1, pSmi->clockRange.minClock, pSmi->clockRange.maxClock, ®->SR6E, ®->SR6F); } + VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, reg->SR6E); VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, reg->SR6F); @@ -866,6 +895,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga; } + crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup; crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; crtcPriv->video_init = SMI730_CrtcVideoInit; crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt; @@ -886,6 +916,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) /* 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; @@ -898,6 +929,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); 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; @@ -918,6 +950,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) 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; commit 439adf4455c651926040eeeec52a092f14f3196b Author: Francisco Jerez <[email protected]> Date: Mon Dec 22 17:28:35 2008 +0100 Add support for clone mode on Lynx chipsets. diff --git a/src/smi_crtc.c b/src/smi_crtc.c index 5bcc471..bccf9b2 100644 --- a/src/smi_crtc.c +++ b/src/smi_crtc.c @@ -85,6 +85,9 @@ static void SMI_CrtcCommit(xf86CrtcPtr crtc) { ENTER(); + + crtc->funcs->dpms(crtc,DPMSModeOn); + LEAVE(); } diff --git a/src/smilynx_crtc.c b/src/smilynx_crtc.c index 616cb81..508184f 100644 --- a/src/smilynx_crtc.c +++ b/src/smilynx_crtc.c @@ -822,6 +822,25 @@ SMILynx_CrtcLoadCursorImage_crt (xf86CrtcPtr crtc, CARD8 *image) LEAVE(); } +static void +SMILynx_CrtcDPMS_crt(xf86CrtcPtr crtc, int mode) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIRegPtr reg = pSmi->mode; + + ENTER(); + + if(mode == DPMSModeOff) + reg->SR21 |= 0x88; /* Disable DAC and color palette RAM */ + else + reg->SR21 &= ~0x88; /* Enable DAC and color palette RAM */ + + VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, reg->SR21); + + LEAVE(); +} + Bool SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) { @@ -840,10 +859,12 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); - if(pSmi->useBIOS) + if(pSmi->useBIOS){ crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios; - else + }else{ + crtcFuncs->dpms = SMILynx_CrtcDPMS_crt; crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga; + } crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; crtcPriv->video_init = SMI730_CrtcVideoInit; @@ -875,6 +896,7 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) /* CRTC1 is CRT */ SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); + crtcFuncs->dpms = SMILynx_CrtcDPMS_crt; crtcFuncs->mode_set = SMILynx_CrtcModeSet_crt; crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; crtcPriv->video_init = SMILynx_CrtcVideoInit_crt; @@ -889,10 +911,12 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) it is controlled through the primary VGA registers */ SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); - if(pSmi->useBIOS) + if(pSmi->useBIOS){ crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios; - else + }else{ + crtcFuncs->dpms = SMILynx_CrtcDPMS_crt; crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga; + } crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; crtcPriv->video_init = SMILynx_CrtcVideoInit_crt; diff --git a/src/smilynx_output.c b/src/smilynx_output.c index 4974d2c..aba6db5 100644 --- a/src/smilynx_output.c +++ b/src/smilynx_output.c @@ -46,22 +46,18 @@ SMILynx_OutputDPMS_crt(xf86OutputPtr output, int mode) switch (mode) { case DPMSModeOn: - reg->SR21 &= ~0x88; /* Enable DAC and color palette RAM */ reg->SR31 |= 0x02; /* Enable CRT display*/ reg->SR22 = (reg->SR22 & ~0x30) | 0x00; /* Set DPMS state*/ break; case DPMSModeStandby: - reg->SR21 |= 0x88; /* Disable DAC and color palette RAM */ reg->SR31 |= 0x02; /* Enable CRT display*/ reg->SR22 = (reg->SR22 & ~0x30) | 0x10; /* Set DPMS state*/ break; case DPMSModeSuspend: - reg->SR21 |= 0x88; /* Disable DAC and color palette RAM */ reg->SR31 |= 0x02; /* Enable CRT display*/ reg->SR22 = (reg->SR22 & ~0x30) | 0x20; /* Set DPMS state*/ break; case DPMSModeOff: - reg->SR21 |= 0x88; /* Disable DAC and color palette RAM */ reg->SR31 &= ~0x02; /* Disable CRT display*/ reg->SR22 = (reg->SR22 & ~0x30) | 0x30; /* Set DPMS state*/ break; @@ -73,7 +69,6 @@ SMILynx_OutputDPMS_crt(xf86OutputPtr output, int mode) while (!(hwp->readST01(hwp) & 0x8)) ; /* Write the registers */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, reg->SR21); VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, reg->SR22); VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, reg->SR31); @@ -81,7 +76,6 @@ SMILynx_OutputDPMS_crt(xf86OutputPtr output, int mode) } - static void SMILynx_OutputDPMS_lcd(xf86OutputPtr output, int mode) { @@ -210,13 +204,13 @@ SMILynx_OutputDetect_crt(xf86OutputPtr output) SR7D = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x7D); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, mode->SR21 & ~0x80); /* Enable DAC */ + VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, mode->SR21 & ~0x88); /* Enable DAC and color palette RAM */ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x7B, 0x40); /* "TV and RAMDAC Testing Power", Green component */ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x7D, SR7D | 0x10); /* Enable monitor detect */ /* Wait for vertical retrace */ - while (hwp->readST01(hwp) & 0x8) ; while (!(hwp->readST01(hwp) & 0x8)) ; + while (hwp->readST01(hwp) & 0x8) ; status = MMIO_IN8(pSmi->IOBase, 0x3C2) & 0x10; @@ -240,9 +234,14 @@ SMILynx_OutputPreInit(ScrnInfoPtr pScrn) ENTER(); if(pSmi->Chipset == SMI_COUGAR3DR){ - /* CRTC0 is LCD */ + /* Output 0 is LCD */ SMI_OutputFuncsInit_base(&outputFuncs); - outputFuncs->dpms = SMILynx_OutputDPMS_lcd; + + if(pSmi->useBIOS) + outputFuncs->dpms = SMILynx_OutputDPMS_bios; + else + outputFuncs->dpms = SMILynx_OutputDPMS_lcd; + outputFuncs->get_modes = SMI_OutputGetModes_native; outputFuncs->detect = SMI_OutputDetect_lcd; @@ -254,22 +253,30 @@ SMILynx_OutputPreInit(ScrnInfoPtr pScrn) output->interlaceAllowed = FALSE; output->doubleScanAllowed = FALSE; }else{ - if(pSmi->Dualhead){ - /* CRTC0 is LCD*/ - SMI_OutputFuncsInit_base(&outputFuncs); + /* Output 0 is LCD */ + SMI_OutputFuncsInit_base(&outputFuncs); + + if(pSmi->useBIOS) + outputFuncs->dpms = SMILynx_OutputDPMS_bios; + else outputFuncs->dpms = SMILynx_OutputDPMS_lcd; - outputFuncs->get_modes = SMI_OutputGetModes_native; - outputFuncs->detect = SMI_OutputDetect_lcd; - if(! (output = xf86OutputCreate(pScrn,outputFuncs,"LVDS"))) - LEAVE(FALSE); + outputFuncs->get_modes = SMI_OutputGetModes_native; + outputFuncs->detect = SMI_OutputDetect_lcd; + + if(! (output = xf86OutputCreate(pScrn,outputFuncs,"LVDS"))) + LEAVE(FALSE); - output->possible_crtcs = 1 << 0; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + output->possible_crtcs = 1 << 0; + if(pSmi->Dualhead) output->possible_clones = 0; - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; + else + output->possible_clones = 1 << 1; - /* CRTC1 is CRT*/ + if(!pSmi->useBIOS){ + /* Output 1 is CRT */ SMI_OutputFuncsInit_base(&outputFuncs); outputFuncs->dpms = SMILynx_OutputDPMS_crt; outputFuncs->get_modes = SMILynx_OutputGetModes_crt; @@ -278,29 +285,16 @@ SMILynx_OutputPreInit(ScrnInfoPtr pScrn) if(! (output = xf86OutputCreate(pScrn,outputFuncs,"VGA"))) LEAVE(FALSE); - output->possible_crtcs = 1 << 1; - output->possible_clones = 0; output->interlaceAllowed = FALSE; output->doubleScanAllowed = FALSE; - }else{ - /* CRTC0 is LCD */ - SMI_OutputFuncsInit_base(&outputFuncs); - - if(pSmi->useBIOS) - outputFuncs->dpms = SMILynx_OutputDPMS_bios; - else - outputFuncs->dpms = SMILynx_OutputDPMS_lcd; - outputFuncs->get_modes = SMI_OutputGetModes_native; - outputFuncs->detect = SMI_OutputDetect_lcd; - - if(! (output = xf86OutputCreate(pScrn,outputFuncs,"LVDS"))) - LEAVE(FALSE); - - output->possible_crtcs = 1 << 0; - output->possible_clones = 0; - 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; + } } } commit 2b3fa385a6da4be5ad6719dd115834b96d1ea3e3 Author: Francisco Jerez <[email protected]> Date: Sun Dec 21 19:37:14 2008 +0100 Add a CRTC/Output implementation using BIOS for modesetting. After the RandR1.2 implementation the "UseBIOS" option wasn't actually programming the hardware through VESA BIOS, this brings back that functionality. diff --git a/src/smilynx_crtc.c b/src/smilynx_crtc.c index 08d798e..616cb81 100644 --- a/src/smilynx_crtc.c +++ b/src/smilynx_crtc.c @@ -524,6 +524,90 @@ SMILynx_CrtcModeSet_lcd(xf86CrtcPtr crtc, } static void +SMILynx_CrtcModeSet_bios(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode, + int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIRegPtr reg = pSmi->mode; + int i; + CARD8 tmp; + + ENTER(); + + /* Find the INT 10 mode number */ + { + static struct { + int x, y, bpp; + CARD16 mode; + } modeTable[] = + { + { 640, 480, 8, 0x50 }, + { 640, 480, 16, 0x52 }, + { 640, 480, 24, 0x53 }, + { 640, 480, 32, 0x54 }, + { 800, 480, 8, 0x4A }, + { 800, 480, 16, 0x4C }, + { 800, 480, 24, 0x4D }, + { 800, 600, 8, 0x55 }, + { 800, 600, 16, 0x57 }, + { 800, 600, 24, 0x58 }, + { 800, 600, 32, 0x59 }, + { 1024, 768, 8, 0x60 }, + { 1024, 768, 16, 0x62 }, + { 1024, 768, 24, 0x63 }, + { 1024, 768, 32, 0x64 }, + { 1280, 1024, 8, 0x65 }, + { 1280, 1024, 16, 0x67 }, + { 1280, 1024, 24, 0x68 }, + { 1280, 1024, 32, 0x69 }, + }; + + reg->mode = 0; + for (i = 0; i < sizeof(modeTable) / sizeof(modeTable[0]); i++) { + if ((modeTable[i].x == mode->HDisplay) && + (modeTable[i].y == mode->VDisplay) && + (modeTable[i].bpp == pScrn->bitsPerPixel)) { + reg->mode = modeTable[i].mode; + break; + } + } + } + + if(!reg->mode){ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SMILynx_CrtcModeSet_bios: Not a known BIOS mode: " + "falling back to direct modesetting.\n"); + SMILynx_CrtcModeSet_vga(crtc,mode,adjusted_mode,x,y); + LEAVE(); + } + + pSmi->pInt10->num = 0x10; + pSmi->pInt10->ax = reg->mode | 0x80; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n", + reg->mode); + xf86ExecX86int10(pSmi->pInt10); + + /* Enable linear mode. */ + outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); + tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); + outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x01); + + /* Enable DPR/VPR registers. */ + tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); + VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); + + + /* Initialize Video Processor Registers */ + + SMICRTC(crtc)->video_init(crtc); + SMILynx_CrtcAdjustFrame(crtc, x,y); + + LEAVE(); +} + +static void SMILynx_CrtcLoadLUT_crt(xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; @@ -755,7 +839,12 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) functions. Has someone access to this hardware? */ SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); - crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga; + + if(pSmi->useBIOS) + crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios; + else + crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga; + crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; crtcPriv->video_init = SMI730_CrtcVideoInit; crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt; @@ -799,7 +888,12 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) /* CRTC0 is LCD, but in standard refresh mode it is controlled through the primary VGA registers */ SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); - crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga; + + if(pSmi->useBIOS) + crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios; + else + crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga; + crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; crtcPriv->video_init = SMILynx_CrtcVideoInit_crt; crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt; diff --git a/src/smilynx_hw.c b/src/smilynx_hw.c index 115a442..8d2c523 100644 --- a/src/smilynx_hw.c +++ b/src/smilynx_hw.c @@ -54,76 +54,78 @@ SMILynx_HWInit(ScrnInfoPtr pScrn) mode->SR17 &= ~0x20; } - /* Disable DAC and LCD framebuffer r/w operation */ - mode->SR21 |= 0xB0; + /* Gamma correction */ + if (pSmi->Chipset == SMI_LYNX3DM || pSmi->Chipset == SMI_COUGAR3DR) { + if(pScrn->bitsPerPixel == 8) + mode->SR66 = (mode->SR66 & 0x33) | 0x00; /* Both RAMLUT on, 6 bits-RAM */ + else + mode->SR66 = (mode->SR66 & 0x33) | 0x04; /* Both RAMLUT on, Gamma correct ON */ + } - /* Power down mode is standby mode, VCLK and MCLK divided by 4 in standby mode */ - mode->SR20 = (mode->SR20 & ~0xB0) | 0x10; + /* Program MCLK */ + if (pSmi->MCLK > 0) + SMI_CommonCalcClock(pScrn->scrnIndex, pSmi->MCLK, + 1, 1, 63, 0, 0, + pSmi->clockRange.minClock, + pSmi->clockRange.maxClock, + &mode->SR6A, &mode->SR6B); - /* Set DPMS state to Off */ -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected]

