diff options
Diffstat (limited to 'main/xf86-video-openchrome/openchrome-0.2.904-svn921.patch')
-rw-r--r-- | main/xf86-video-openchrome/openchrome-0.2.904-svn921.patch | 4427 |
1 files changed, 4427 insertions, 0 deletions
diff --git a/main/xf86-video-openchrome/openchrome-0.2.904-svn921.patch b/main/xf86-video-openchrome/openchrome-0.2.904-svn921.patch new file mode 100644 index 000000000..a26382b60 --- /dev/null +++ b/main/xf86-video-openchrome/openchrome-0.2.904-svn921.patch @@ -0,0 +1,4427 @@ +Index: ChangeLog +=================================================================== +--- ChangeLog (revision 811) ++++ ChangeLog (working copy) +@@ -1,3 +1,225 @@ ++2011-05-04 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Fix XAA displaying issues ++ ++ * src/via_accel.c: (viaInitXAA): ++ ++2011-01-23 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Enable hardware cursor for VX900 ++ ++ * src/via_cursor.c: (viaHWCursorInit): ++ * src/via_mode.c: (ViaModeSet): ++ ++2010-12-16 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Merge vx900_branch - initial VX900 support ++ ++ * src/via_accel.c: (viaFlushPCI), (viaDisableVQ), ++ (viaInitialize2DEngine), (viaAccelSync), (viaPitchHelper), ++ (viaInitXAA): ++ * src/via_bandwidth.c: (ViaSetPrimaryFIFO), (ViaSetSecondaryFIFO): ++ * src/via_bios.h: ++ * src/via_crtc.c: (ViaFirstCRTCSetMode), (ViaSecondCRTCSetMode): ++ * src/via_cursor.c: (viaHWCursorInit), (viaCursorStore), ++ (viaCursorRestore), (viaShowCursor), (viaHideCursor), ++ (viaSetCursorPosition), (viaLoadCursorImage), (viaSetCursorColors): ++ * src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit), ++ (VIALeaveVT), (VIASave), (VIARestore), (ViaMMIOEnable), ++ (ViaMMIODisable), (VIAMapFB), (VIAWriteMode), (VIACloseScreen): ++ * src/via_driver.h: ++ * src/via_id.c: ++ * src/via_id.h: ++ * src/via_mode.c: (ViaDFPDetect), (ViaOutputsDetect), ++ (ViaOutputsSelect), (ViaGetMemoryBandwidth), (ViaSetDotclock), ++ (ViaModeSet): ++ * src/via_mode.h: ++ * src/via_panel.c: (ViaPanelScaleDisable), (ViaPanelPreInit), ++ (ViaPanelGetSizeFromDDC): ++ * src/via_video.c: (DecideOverlaySupport): ++ * src/via_xvmc.c: (ViaInitXVMC): ++ ++2010-12-15 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Enable the new mode switch and panel support on K8M800 and VM800 chipsets ++ ++ * src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit): ++ * src/via_mode.c: (ViaModeSet): ++ ++2010-11-10 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Replace the deprecated functions ++ xalloc/xrealloc/xfree/xcalloc with ++ malloc/realloc/free/calloc. ++ Refer to "/xserver/include/os.h" ++ ++ * src/via_accel.c: (viaSetupCBuffer), (viaTearDownCBuffer), ++ (viaInitExa), (viaExitAccel), (viaFinishInitAccel): ++ * src/via_dga.c: (VIASetupDGAMode): ++ * src/via_dri.c: (VIAInitVisualConfigs), (VIADRIScreenInit), ++ (VIADRICloseScreen): ++ * src/via_driver.c: (VIAFreeRec), (VIAProbe), (VIAPreInit), ++ (VIACloseScreen): ++ * src/via_memcpy.c: (viaVidCopyInit): ++ * src/via_swov.c: (Upd_Video): ++ * src/via_vbe.c: (ViaVbeSetMode): ++ * src/via_video.c: (viaExitVideo), (viaStopVideo), ++ (viaDmaBlitImage): ++ * src/via_xvmc.c: (cleanupViaXvMC), (ViaCleanupXVMC), ++ (ViaXvMCCreateContext), (ViaXvMCCreateSurface), ++ (ViaXvMCCreateSubpicture), (ViaXvMCDestroyContext), ++ (ViaXvMCDestroySurface), (ViaXvMCDestroySubpicture), ++ (viaXvMCInitXv): ++ ++2010-10-24 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Siragon ML-6200 laptop support ++ ++ * src/via_id.c: ++ ++2010-06-24 Jon Nettleton <jon.nettleton@gmail.com> ++ ++ PM800 also uses the CME Engine. Setup the hqv_cme_regs ++ for it. ++ ++ * src/via_swov.c: (VIAVidHWDiffInit): ++ ++2010-06-09 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Fix freeze on 64bit system for K8M800 chipset ++ ++ * src/via_dri.c: (VIADRIAgpInit): ++ ++2010-05-04 Jon Nettleton <jon.nettleton@gmail.com> ++ ++ Re-enable the Virtual Queue for the VX800/VX855 chipsets. ++ ++ * src/via_accel.c: (viaDisableVQ), (viaInitialize2DEngine): ++ ++2010-05-04 Jon Nettleton <jon.nettleton@gmail.com> ++ ++ Disable certain hardware clipping options for the VX855. ++ These cause the 2d engine to become unstable when in ++ 16-bit mode. ++ ++ * src/via_accel.c: (viaInitXAA): ++ ++2010-05-04 Jon Nettleton <jon.nettleton@gmail.com> ++ ++ Add an undocumented option which allows certain I2C buses ++ to be probed at startup. This allows workarounds for custom ++ chipset makers that have used the VX855 I2C buses for other ++ purposes. ++ ++ * src/via_bios.h: ++ * src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit): ++ * src/via_driver.h: ++ * src/via_i2c.c: ++ ++2010-05-04 Jon Nettleton <jon.nettleton@gmail.com> ++ ++ Improve 2d performance on chipsets that don't have ++ AGP/PCIe support yet. ++ ++ * src/via_accel.c: (viaSetupForScreenToScreenCopy), ++ (viaSetupForSolidFill), (viaSetupForMono8x8PatternFill), ++ (viaSetupForColor8x8PatternFill), ++ (viaSetupForCPUToScreenColorExpandFill), ++ (viaSubsequentScanlineCPUToScreenColorExpandFill), ++ (viaSetupForImageWrite), (viaSubsequentImageWriteRect), ++ (viaSetupForSolidLine), (viaSetupForDashedLine), (viaInitXAA): ++ ++2010-05-04 Jon Nettleton <jon.nettleton@gmail.com> ++ ++ Put timeouts on our while statements. These codepaths ++ should be interrupted by a hardware state change, but ++ if something goes wrong they loop forevere. Let's try ++ and behave a little by putting a timeout on these loops. ++ ++ * src/via_swov.c: (viaWaitHQVFlip), (viaWaitHQVFlipClear), ++ (viaWaitHQVDone): ++ * src/via_video.c: (Flip): ++ ++2010-05-04 Jon Nettleton <jon.nettleton@gmail.com> ++ ++ Add XVideo support for the VX855 Chipset. ++ To support this chipset I have added HWDiff->HQVCmeRegs ++ that allows handling differing register values, and ++ HWDiff->dwNewScaleCtl which allows selection of a ++ new Video scaling engine needed for the VX800/VX855 ++ chipsets. ++ ++ * src/via.h: ++ * src/via_bandwidth.c: (ViaSetSecondaryFIFO): ++ * src/via_driver.h: ++ * src/via_swov.c: (SaveVideoRegister), (VIAVidHWDiffInit), ++ (viaOverlayHQVCalcZoomWidth), (viaOverlayHQVCalcZoomHeight), ++ (ViaSwovSurfaceCreate), (SetHQVFetch), (Upd_Video): ++ * src/via_swov.h: ++ ++2010-04-21 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Replace RegionsEqual with REGION_EQUAL and use ++ the xf86XVFillKeyHelperDrawable instead of xf86XVFillKeyHelper ++ ++ * src/via_video.c: (viaReputImage), (viaPutImage): ++ ++2010-03-07 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Fix segfaults with EXA and XV (Ticket #359) ++ Tested on K8M890 and VN800 ++ ++ * src/via_video.c: (viaReputImage), (viaPutImage): ++ ++2010-02-10 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Fix bug with suspend and VT switch on VX800 and 64bit systems ++ ++ * src/via_driver.h: ++ * src/via_video.c: (viaResetVideo), (viaSaveVideo), ++ (viaRestoreVideo), (viaExitVideo): ++ * src/via_video.h: ++ ++2010-01-24 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Fix starting address restore and save (initial 64-bit support) ++ ++ * src/via_crtc.c: (ViaFirstCRTCSetMode), ++ (ViaFirstCRTCSetStartingAddress): ++ * src/via_dri.c: (VIADRIAgpInit): ++ * src/via_driver.c: (VIASave), (VIARestore): ++ * src/via_driver.h: ++ ++2009-12-04 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Enable new mode switch for VM800 chipsets ++ ++ * src/via_driver.c: (VIASetupDefaultOptions): ++ ++2009-11-21 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Add option to enable unaccelerated RandR rotation ("SWRandR"). ++ The accelerated option "HWRandR" is currently not implemented. ++ ++ * src/openchrome.man: ++ * src/via_driver.c: (VIAPreInit): ++ ++2009-11-20 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Enabled new mode switch for PM800 chipset, ++ to resolve many bugs with resolution detecting and changing ++ (eg. switching to console) ++ ++ * src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit): ++ ++2009-11-07 Bartosz Kosiorek <gang65@poczta.onet.pl> ++ ++ Add more comments to ViaSetSecondaryFIFO, add panel scale support for ++ CLE266 and KM400, fix bug with malloc. ++ ++ * src/via_bandwidth.c: (ViaSetSecondaryFIFO): ++ * src/via_panel.c: (ViaPanelScale), (ViaPanelGetNativeDisplayMode): ++ + 2009-09-26 Bartosz Kosiorek <gang65@poczta.onet.pl> + + Save/restore ECK Clock Synthesizer +Index: src/via_panel.c +=================================================================== +--- src/via_panel.c (revision 811) ++++ src/via_panel.c (working copy) +@@ -45,17 +45,17 @@ + {1280, 768}, + {1280, 1024}, + {1400, 1050}, +- {1600, 1200}, /* 0x6 Resolution 1440x900 */ ++ {1600, 1200}, /* 0x6 */ + {1280, 800}, /* 0x7 Resolution 1280x800 (Samsung NC20) */ + {800, 480}, /* 0x8 For Quanta 800x480 */ + {1024, 600}, /* 0x9 Resolution 1024x600 (for HP 2133) */ + {1366, 768}, /* 0xA Resolution 1366x768 */ + {1920, 1080}, + {1920, 1200}, +- {1280, 1024}, /* 0xD Need to be fixed to 1920x1200 */ +- {1440, 900}, /* 0xE Need to be fixed to 640x240 */ ++ {1280, 1024}, /* 0xD */ ++ {1440, 900}, /* 0xE */ + {1280, 720}, /* 0xF 480x640 */ +- {1200, 900}, /* 0x10 For Panasonic 1280x768 18bit Dual-Channel Panel */ ++ {1200, 900}, /* 0x10 For OLPC 1.5 */ + {1360, 768}, /* 0x11 Resolution 1360X768 */ + {1024, 768}, /* 0x12 Resolution 1024x768 */ + {800, 480} /* 0x13 General 8x4 panel use this setting */ +@@ -147,6 +147,9 @@ + vgaHWPtr hwp = VGAHWPTR(pScrn); + + ViaCrtcMask(hwp, 0x79, 0x00, 0x01); ++ /* Disable VX900 down scaling */ ++ if (pVia->Chipset == VIA_VX900) ++ ViaCrtcMask(hwp, 0x89, 0x00, 0x01); + if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) + ViaCrtcMask(hwp, 0xA2, 0x00, 0xC8); + } +@@ -171,12 +174,18 @@ + resWidth, resHeight, panelWidth, panelHeight)); + + if (resWidth < panelWidth) { +- /* FIXME: It is different for chipset < K8M800 */ +- horScalingFactor = ((resWidth - 1) * 4096) / (panelWidth - 1); ++ /* Load Horizontal Scaling Factor */ ++ if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) { ++ horScalingFactor = ((resWidth - 1) * 4096) / (panelWidth - 1); ++ ++ /* Horizontal scaling enabled */ ++ cra2 = 0xC0; ++ cr9f = horScalingFactor & 0x0003; /* HSCaleFactor[1:0] at CR9F[1:0] */ ++ } else { ++ /* TODO: Need testing */ ++ horScalingFactor = ((resWidth - 1) * 1024) / (panelWidth - 1); ++ } + +- /* Horizontal scaling enabled */ +- cra2 = 0xC0; +- cr9f = horScalingFactor & 0x0003; /* HSCaleFactor[1:0] at CR9F[1:0] */ + cr77 = (horScalingFactor & 0x03FC) >> 2; /* HSCaleFactor[9:2] at CR77[7:0] */ + cr79 = (horScalingFactor & 0x0C00) >> 10; /* HSCaleFactor[11:10] at CR79[5:4] */ + cr79 <<= 4; +@@ -184,11 +193,18 @@ + } + + if (resHeight < panelHeight) { +- verScalingFactor = ((resHeight - 1) * 2048) / (panelHeight - 1); ++ /* Load Vertical Scaling Factor */ ++ if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) { ++ verScalingFactor = ((resHeight - 1) * 2048) / (panelHeight - 1); + +- /* Vertical scaling enabled */ +- cra2 |= 0x08; +- cr79 |= ((verScalingFactor & 0x0001) << 3); /* VSCaleFactor[0] at CR79[3] */ ++ /* Vertical scaling enabled */ ++ cra2 |= 0x08; ++ cr79 |= ((verScalingFactor & 0x0001) << 3); /* VSCaleFactor[0] at CR79[3] */ ++ } else { ++ /* TODO: Need testing */ ++ verScalingFactor = ((resHeight - 1) * 1024) / (panelHeight - 1); ++ } ++ + cr78 |= (verScalingFactor & 0x01FE) >> 1; /* VSCaleFactor[8:1] at CR78[7:0] */ + cr79 |= ((verScalingFactor & 0x0600) >> 9) << 6; /* VSCaleFactor[10:9] at CR79[7:6] */ + scaling = TRUE; +@@ -203,13 +219,19 @@ + ViaCrtcMask(hwp, 0x77, cr77, 0xFF); + ViaCrtcMask(hwp, 0x78, cr78, 0xFF); + ViaCrtcMask(hwp, 0x79, cr79, 0xF8); +- ViaCrtcMask(hwp, 0x9F, cr9f, 0x03); ++ if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) { ++ ViaCrtcMask(hwp, 0x9F, cr9f, 0x03); ++ } + ViaCrtcMask(hwp, 0x79, 0x03, 0x03); +- } else ++ } else { ++ /* Disable panel scale */ + ViaCrtcMask(hwp, 0x79, 0x00, 0x01); ++ } ++ ++ if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) { ++ ViaCrtcMask(hwp, 0xA2, cra2, 0xC8); ++ } + +- ViaCrtcMask(hwp, 0xA2, cra2, 0xC8); +- + /* Horizontal scaling selection: interpolation */ + // ViaCrtcMask(hwp, 0x79, 0x02, 0x02); + // else +@@ -233,14 +255,14 @@ + + if (panelMode->Width && panelMode->Height) { + +- /* TODO: fix refresh rate and check malloc */ ++ /* TODO: fix refresh rate */ + DisplayModePtr p = malloc( sizeof(DisplayModeRec) ) ; +- memset(p, 0, sizeof(DisplayModeRec)); ++ if (p) { ++ memset(p, 0, sizeof(DisplayModeRec)); + +- float refresh = 60.0f ; ++ float refresh = 60.0f ; + +- /* The following code is borrowed from xf86SetModeCrtc. */ +- if (p) { ++ /* The following code is borrowed from xf86SetModeCrtc. */ + viaTimingCvt(p, panelMode->Width, panelMode->Height, refresh, FALSE, TRUE); + p->CrtcHDisplay = p->HDisplay; + p->CrtcHSyncStart = p->HSyncStart; +@@ -256,9 +278,13 @@ + p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal); + p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay); + p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal); +- ++ ++ pVia->pBIOSInfo->Panel->NativeDisplayMode = p; ++ } else { ++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, ++ "Out of memory. Size: %d bytes\n", sizeof(DisplayModeRec)); + } +- pVia->pBIOSInfo->Panel->NativeDisplayMode = p; ++ + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Invalid panel dimension (%dx%d)\n", panelMode->Width, +@@ -282,10 +308,7 @@ + Bool ret; + + ret = ViaPanelGetSizeFromDDCv1(pScrn, &width, &height); +-/* +- if (!ret) +- ret = ViaPanelGetSizeFromDDCv2(pScrn, &width); +-*/ ++ + if (ret) { + panel->NativeModeIndex = ViaPanelLookUpModeIndex(width, height); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelLookUpModeIndex, Width %d, Height %d, NativeModeIndex%d\n", width, height, panel->NativeModeIndex)); +@@ -333,28 +356,28 @@ + + + /* +- * Try to interprete EDID ourselves. ++ * Try to interpret EDID ourselves. + */ + Bool + ViaPanelGetSizeFromEDID(ScrnInfoPtr pScrn, xf86MonPtr pMon, + int *width, int *height) + { +- int i, max = 0, vsize; ++ int i, max_hsize = 0, vsize = 0; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromEDID\n")); + + /* !!! Why are we not checking VESA modes? */ + + /* checking standard timings */ +- for (i = 0; i < 8; i++) ++ for (i = 0; i < STD_TIMINGS; i++) + if ((pMon->timings2[i].hsize > 256) +- && (pMon->timings2[i].hsize > max)) { +- max = pMon->timings2[i].hsize; ++ && (pMon->timings2[i].hsize > max_hsize)) { ++ max_hsize = pMon->timings2[i].hsize; + vsize = pMon->timings2[i].vsize; + } + +- if (max != 0) { +- *width = max; ++ if (max_hsize != 0) { ++ *width = max_hsize; + *height = vsize; + return TRUE; + } +@@ -369,14 +392,14 @@ + struct detailed_timings timing = pMon->det_mon[i].section.d_timings; + + /* ignore v_active for now */ +- if ((timing.clock > 15000000) && (timing.h_active > max)) { +- max = timing.h_active; ++ if ((timing.clock > 15000000) && (timing.h_active > max_hsize)) { ++ max_hsize = timing.h_active; + vsize = timing.v_active; + } + } + +- if (max != 0) { +- *width = max; ++ if (max_hsize != 0) { ++ *width = max_hsize; + *height = vsize; + return TRUE; + } +@@ -386,7 +409,6 @@ + + Bool + ViaPanelGetSizeFromDDCv1(ScrnInfoPtr pScrn, int *width, int *height) +- + { + VIAPtr pVia = VIAPTR(pScrn); + xf86MonPtr pMon; +@@ -396,7 +418,7 @@ + if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA0)) + return FALSE; + +- pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus2); ++ pMon = xf86DoEEDID(pScrn->scrnIndex, pVia->pI2CBus2, TRUE); + if (!pMon) + return FALSE; + +Index: src/via_id.h +=================================================================== +--- src/via_id.h (revision 811) ++++ src/via_id.h (working copy) +@@ -39,6 +39,7 @@ + VIA_P4M890, + VIA_VX800, + VIA_VX855, ++ VIA_VX900, + VIA_LAST + }; + +@@ -56,6 +57,7 @@ + #define PCI_CHIP_VT3327 0x3343 /* P4M890 */ + #define PCI_CHIP_VT3353 0x1122 /* VX800 */ + #define PCI_CHIP_VT3409 0x5122 /* VX855/VX875 */ ++#define PCI_CHIP_VT3410 0x7122 /* VX900 */ + + /* There is some conflicting information about the two major revisions of + * the CLE266, often labelled Ax and Cx. The dividing line seems to be +Index: src/via_video.c +=================================================================== +--- src/via_video.c (revision 811) ++++ src/via_video.c (working copy) +@@ -354,6 +354,14 @@ + mClock = 333; + memEfficiency = (float)SINGLE_3205_133; + break; ++ case VIA_MEM_DDR800: ++ mClock = 400; ++ memEfficiency = (float)SINGLE_3205_133; ++ break; ++ case VIA_MEM_DDR1066: ++ mClock = 533; ++ memEfficiency = (float)SINGLE_3205_133; ++ break; + default: + /*Unknow DRAM Type */ + DBG_DD(ErrorF("Unknow DRAM Type!\n")); +@@ -426,7 +434,7 @@ + DBG_DD(ErrorF(" via_video.c : totalBandwidth= %f : \n", + totalBandWidth)); + if (needBandWidth < totalBandWidth) +- return TRUE; ++ return TRUE; + } + return FALSE; + } +@@ -466,8 +474,8 @@ + + viaVidEng->video1_ctl = 0; + viaVidEng->video3_ctl = 0; +- viaVidEng->compose = 0x80000000; +- viaVidEng->compose = 0x40000000; ++ viaVidEng->compose = V1_COMMAND_FIRE; ++ viaVidEng->compose = V3_COMMAND_FIRE; + viaVidEng->color_key = 0x821; + viaVidEng->snd_color_key = 0x821; + +@@ -479,16 +487,16 @@ + VIAPtr pVia = VIAPTR(pScrn); + vmmtr viaVidEng = (vmmtr) pVia->VidMapBase; + ++ DBG_DD(ErrorF(" via_video.c : viaSaveVideo : \n")); + /* Save video registers */ +- /* TODO: Identify which registers should be saved and restored */ + memcpy(pVia->VideoRegs, (void*)viaVidEng, sizeof(video_via_regs)); + + pVia->dwV1 = ((vmmtr) viaVidEng)->video1_ctl; + pVia->dwV3 = ((vmmtr) viaVidEng)->video3_ctl; + viaVidEng->video1_ctl = 0; + viaVidEng->video3_ctl = 0; +- viaVidEng->compose = 0x80000000; +- viaVidEng->compose = 0x40000000; ++ viaVidEng->compose = V1_COMMAND_FIRE; ++ viaVidEng->compose = V3_COMMAND_FIRE; + } + + void +@@ -496,16 +504,66 @@ + { + VIAPtr pVia = VIAPTR(pScrn); + vmmtr viaVidEng = (vmmtr) pVia->VidMapBase; ++ video_via_regs *localVidEng = pVia->VideoRegs; ++ + ++ DBG_DD(ErrorF(" via_video.c : viaRestoreVideo : \n")); + /* Restore video registers */ +- /* TODO: Identify which registers should be saved and restored */ +- memcpy((void*)viaVidEng, pVia->VideoRegs, sizeof(video_via_regs)); ++ /* flush restored video engines' setting to VidMapBase */ ++ ++ viaVidEng->alphawin_hvstart = localVidEng->alphawin_hvstart; ++ viaVidEng->alphawin_size = localVidEng->alphawin_size; ++ viaVidEng->alphawin_ctl = localVidEng->alphawin_ctl; ++ viaVidEng->alphafb_stride = localVidEng->alphafb_stride; ++ viaVidEng->color_key = localVidEng->color_key; ++ viaVidEng->alphafb_addr = localVidEng->alphafb_addr; ++ viaVidEng->chroma_low = localVidEng->chroma_low; ++ viaVidEng->chroma_up = localVidEng->chroma_up; ++ viaVidEng->interruptflag = localVidEng->interruptflag; + ++ if (pVia->ChipId != PCI_CHIP_VT3314) ++ { ++ /*VT3314 only has V3*/ ++ viaVidEng->video1_ctl = localVidEng->video1_ctl; ++ viaVidEng->video1_fetch = localVidEng->video1_fetch; ++ viaVidEng->video1y_addr1 = localVidEng->video1y_addr1; ++ viaVidEng->video1_stride = localVidEng->video1_stride; ++ viaVidEng->video1_hvstart = localVidEng->video1_hvstart; ++ viaVidEng->video1_size = localVidEng->video1_size; ++ viaVidEng->video1y_addr2 = localVidEng->video1y_addr2; ++ viaVidEng->video1_zoom = localVidEng->video1_zoom; ++ viaVidEng->video1_mictl = localVidEng->video1_mictl; ++ viaVidEng->video1y_addr0 = localVidEng->video1y_addr0; ++ viaVidEng->video1_fifo = localVidEng->video1_fifo; ++ viaVidEng->video1y_addr3 = localVidEng->video1y_addr3; ++ viaVidEng->v1_source_w_h = localVidEng->v1_source_w_h ; ++ viaVidEng->video1_CSC1 = localVidEng->video1_CSC1; ++ viaVidEng->video1_CSC2 = localVidEng->video1_CSC2; ++ } ++ viaVidEng->snd_color_key = localVidEng->snd_color_key; ++ viaVidEng->v3alpha_prefifo = localVidEng->v3alpha_prefifo; ++ viaVidEng->v3alpha_fifo = localVidEng->v3alpha_fifo; ++ viaVidEng->video3_CSC2 = localVidEng->video3_CSC2; ++ viaVidEng->video3_CSC2 = localVidEng->video3_CSC2; ++ viaVidEng->v3_source_width = localVidEng->v3_source_width; ++ viaVidEng->video3_ctl = localVidEng->video3_ctl; ++ viaVidEng->video3_addr0 = localVidEng->video3_addr0; ++ viaVidEng->video3_addr1 = localVidEng->video3_addr1; ++ viaVidEng->video3_stride = localVidEng->video3_stride; ++ viaVidEng->video3_hvstart = localVidEng->video3_hvstart; ++ viaVidEng->video3_size = localVidEng->video3_size; ++ viaVidEng->v3alpha_fetch = localVidEng->v3alpha_fetch; ++ viaVidEng->video3_zoom = localVidEng->video3_zoom; ++ viaVidEng->video3_mictl = localVidEng->video3_mictl; ++ viaVidEng->video3_CSC1 = localVidEng->video3_CSC1; ++ viaVidEng->video3_CSC2 = localVidEng->video3_CSC2; ++ viaVidEng->compose = localVidEng->compose; ++ + viaVidEng->video1_ctl = pVia->dwV1; + viaVidEng->video3_ctl = pVia->dwV3; +- viaVidEng->compose = 0x80000000; +- viaVidEng->compose = 0x40000000; +- ++ if (pVia->ChipId != PCI_CHIP_VT3314) ++ viaVidEng->compose = V1_COMMAND_FIRE; ++ viaVidEng->compose = V3_COMMAND_FIRE; + } + + void +@@ -524,8 +582,8 @@ + + viaVidEng->video1_ctl = 0; + viaVidEng->video3_ctl = 0; +- viaVidEng->compose = 0x80000000; +- viaVidEng->compose = 0x40000000; ++ viaVidEng->compose = V1_COMMAND_FIRE; ++ viaVidEng->compose = V3_COMMAND_FIRE; + + /* + * Free all adaptor info allocated in viaInitVideo. +@@ -542,15 +600,15 @@ + (viaPortPrivPtr) curAdapt->pPortPrivates->ptr + j, + TRUE); + } +- xfree(curAdapt->pPortPrivates->ptr); ++ free(curAdapt->pPortPrivates->ptr); + } +- xfree(curAdapt->pPortPrivates); ++ free(curAdapt->pPortPrivates); + } +- xfree(curAdapt); ++ free(curAdapt); + } + } + if (allAdaptors) +- xfree(allAdaptors); ++ free(allAdaptors); + } + + void +@@ -561,7 +619,7 @@ + XF86VideoAdaptorPtr *adaptors, *newAdaptors; + int num_adaptors, num_new; + +- DBG_DD(ErrorF(" via_video.c : viaInitVideo : \n")); ++ DBG_DD(ErrorF(" via_video.c : viaInitVideo, Screen[%d]\n", pScrn->scrnIndex)); + + allAdaptors = NULL; + newAdaptors = NULL; +@@ -611,7 +669,7 @@ + + DBG_DD(ErrorF(" via_video.c : num_adaptors : %d\n", num_adaptors)); + if (newAdaptors) { +- allAdaptors = xalloc((num_adaptors + num_new) * ++ allAdaptors = malloc((num_adaptors + num_new) * + sizeof(XF86VideoAdaptorPtr *)); + if (allAdaptors) { + if (num_adaptors) +@@ -636,194 +694,6 @@ + } + } + +-static Bool +-RegionsEqual(RegionPtr A, RegionPtr B) +-{ +- int *dataA, *dataB; +- int num; +- +- num = REGION_NUM_RECTS(A); +- if (num != REGION_NUM_RECTS(B)) +- return FALSE; +- +- if ((A->extents.x1 != B->extents.x1) || +- (A->extents.x2 != B->extents.x2) || +- (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) +- return FALSE; +- +- dataA = (int *)REGION_RECTS(A); +- dataB = (int *)REGION_RECTS(B); +- +- while (num--) { +- if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) +- return FALSE; +- dataA += 2; +- dataB += 2; +- } +- +- return TRUE; +-} +- +-static void +-viaVideoFillPixmap(ScrnInfoPtr pScrn, +- char *base, +- unsigned long pitch, +- int depth, +- int x, int y, int w, int h, +- unsigned long color) +-{ +- int i; +- +- ErrorF("pitch %lu, depth %d, x %d, y %d, w %d, h %d, color 0x%08lx\n", +- pitch, depth, x, y, w, h, color); +- +- depth = (depth + 7) >> 3; +- +- base += y*pitch + x*depth; +- +- switch(depth) { +- case 4: +- while(h--) { +- register CARD32 *p = (CARD32 *)base; +- for (i=0; i<w; ++i) { +- *p++ = color; +- } +- base += pitch; +- } +- break; +- case 2: { +- register CARD16 col = color & 0x0000FFFF; +- while(h--) { +- register CARD16 *p = (CARD16 *)base; +- for (i=0; i<w; ++i) { +- *p++ = col; +- } +- base += pitch; +- } +- break; +- } +- case 1: { +- register CARD8 col = color & 0xFF; +- while(h--) { +- register CARD8 *p = (CARD8 *)base; +- for (i=0; i<w; ++i) { +- *p++ = col; +- } +- base += pitch; +- } +- break; +- } +- default: +- break; +- } +-} +- +- +- +-static int +-viaPaintColorkey(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, RegionPtr clipBoxes, +- DrawablePtr pDraw) +-{ +- +- if (pDraw->type == DRAWABLE_WINDOW) { +- +- VIAPtr pVia = VIAPTR(pScrn); +- PixmapPtr pPix = (pScrn->pScreen->GetWindowPixmap)((WindowPtr) pDraw); +- unsigned long pitch = pPix->devKind; +- long offset = (long) pPix->devPrivate.ptr - (long) pVia->FBBase; +- int x,y; +- BoxPtr pBox; +- int nBox; +- +- REGION_TRANSLATE(pScrn->pScreen, clipBoxes, - pPix->screen_x, +- - pPix->screen_y); +- +- nBox = REGION_NUM_RECTS(clipBoxes); +- pBox = REGION_RECTS(clipBoxes); +- +- while(nBox--) { +- if (pVia->NoAccel || offset < 0 || +- offset > pScrn->videoRam*1024) { +- viaVideoFillPixmap(pScrn, pPix->devPrivate.ptr, pitch, +- pDraw->bitsPerPixel, pBox->x1, pBox->y1, +- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1, +- pPriv->colorKey); +- } else { +- viaAccelFillPixmap(pScrn, offset, pitch, +- pDraw->bitsPerPixel, pBox->x1, pBox->y1, +- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1, +- pPriv->colorKey); +- } +- pBox++; +- } +- +- DamageDamageRegion(pPix, clipBoxes); +- } +- +- return 0; +-} +- +- +-/* +- * This one gets called, for example, on panning. +- */ +- +-static int +-viaReputImage(ScrnInfoPtr pScrn, +- short drw_x, short drw_y, RegionPtr clipBoxes, pointer data, +- DrawablePtr pDraw) +-{ +- +- DDUPDATEOVERLAY UpdateOverlay_Video; +- LPDDUPDATEOVERLAY lpUpdateOverlay = &UpdateOverlay_Video; +- viaPortPrivPtr pPriv = (viaPortPrivPtr) data; +- VIAPtr pVia = VIAPTR(pScrn); +- +- if (!RegionsEqual(&pPriv->clip, clipBoxes)) { +- REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); +- if (pPriv->autoPaint) { +- if (pDraw->type == DRAWABLE_WINDOW) { +- viaPaintColorkey(pScrn, pPriv, clipBoxes, pDraw); +- } else { +- xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, +- clipBoxes); +- } +- } +- } +- +- if (drw_x == pPriv->old_drw_x && +- drw_y == pPriv->old_drw_y && +- pVia->swov.oldPanningX == pVia->swov.panning_x && +- pVia->swov.oldPanningY == pVia->swov.panning_y) { +- viaXvError(pScrn, pPriv, xve_none); +- return Success; +- } +- +- lpUpdateOverlay->SrcLeft = pPriv->old_src_x; +- lpUpdateOverlay->SrcTop = pPriv->old_src_y; +- lpUpdateOverlay->SrcRight = pPriv->old_src_x + pPriv->old_src_w; +- lpUpdateOverlay->SrcBottom = pPriv->old_src_y + pPriv->old_src_h; +- +- lpUpdateOverlay->DstLeft = drw_x; +- lpUpdateOverlay->DstTop = drw_y; +- lpUpdateOverlay->DstRight = drw_x + pPriv->old_drw_w; +- lpUpdateOverlay->DstBottom = drw_y + pPriv->old_drw_h; +- pPriv->old_drw_x = drw_x; +- pPriv->old_drw_y = drw_y; +- +- lpUpdateOverlay->dwFlags = DDOVER_KEYDEST; +- +- if (pScrn->bitsPerPixel == 8) +- lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey & 0xff; +- else +- lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey; +- +- VIAVidUpdateOverlay(pScrn, lpUpdateOverlay); +- +- viaXvError(pScrn, pPriv, xve_none); +- return Success; +-} +- + static unsigned + viaSetupAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr ** adaptors) + { +@@ -832,7 +702,7 @@ + DevUnion *pdevUnion; + int i, j, usedPorts, numPorts; + +- DBG_DD(ErrorF(" via_video.c : viaSetupImageVideo: \n")); ++ DBG_DD(ErrorF(" via_video.c : viaSetupAdaptors (viaSetupImageVideo): \n")); + + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); +@@ -884,7 +754,7 @@ + viaAdaptPtr[i]->GetPortAttribute = viaGetPortAttribute; + viaAdaptPtr[i]->SetPortAttribute = viaSetPortAttribute; + viaAdaptPtr[i]->PutImage = viaPutImage; +- viaAdaptPtr[i]->ReputImage = viaReputImage; ++ viaAdaptPtr[i]->ReputImage = NULL; + viaAdaptPtr[i]->QueryImageAttributes = viaQueryImageAttributes; + for (j = 0; j < numPorts; ++j) { + viaPortPriv[j].dmaBounceBuffer = NULL; +@@ -931,7 +801,7 @@ + if (exit) { + ViaSwovSurfaceDestroy(pScrn, pPriv); + if (pPriv->dmaBounceBuffer) +- xfree(pPriv->dmaBounceBuffer); ++ free(pPriv->dmaBounceBuffer); + pPriv->dmaBounceBuffer = 0; + pPriv->dmaBounceStride = 0; + pPriv->dmaBounceLines = 0; +@@ -1042,6 +912,8 @@ + } + + } else { ++ DBG_DD(ErrorF(" via_video.c : viaGetPortAttribute : is not supported the attribute\n")); ++ + /*return BadMatch */; + } + return Success; +@@ -1070,6 +942,7 @@ + unsigned long DisplayBufferIndex) + { + unsigned long proReg = 0; ++ unsigned count = 50000; + + if (pVia->ChipId == PCI_CHIP_VT3259 + && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) +@@ -1081,7 +954,8 @@ + case FOURCC_RV15: + case FOURCC_RV16: + case FOURCC_RV32: +- while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP)); ++ while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP) ++ && --count); + VIDOutD(HQV_SRC_STARTADDR_Y + proReg, + pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]); + VIDOutD(HQV_CONTROL + proReg, +@@ -1090,7 +964,8 @@ + break; + case FOURCC_YV12: + default: +- while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP)); ++ while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP) ++ && --count); + VIDOutD(HQV_SRC_STARTADDR_Y + proReg, + pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]); + if (pVia->VideoEngine == VIDEO_ENGINE_CME) { +@@ -1174,7 +1049,7 @@ + pPort->dmaBounceStride != bounceStride || + pPort->dmaBounceLines != bounceLines) { + if (pPort->dmaBounceBuffer) { +- xfree(pPort->dmaBounceBuffer); ++ free(pPort->dmaBounceBuffer); + pPort->dmaBounceBuffer = 0; + } + size = bounceStride * bounceLines + 16; +@@ -1296,7 +1171,7 @@ + unsigned long retCode; + + # ifdef XV_DEBUG +- ErrorF(" via_video.c : viaPutImage : called\n"); ++ ErrorF(" via_video.c : viaPutImage : called, Screen[%d]\n", pScrn->scrnIndex); + ErrorF(" via_video.c : FourCC=0x%x width=%d height=%d sync=%d\n", id, + width, height, sync); + ErrorF +@@ -1405,12 +1280,11 @@ + + lpUpdateOverlay->dwFlags = DDOVER_KEYDEST; + +- if (pScrn->bitsPerPixel == 8) +- lpUpdateOverlay->dwColorSpaceLowValue = +- pPriv->colorKey & 0xff; +- else +- lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey; +- ++ if (pScrn->bitsPerPixel == 8) { ++ lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey & 0xff; ++ } else { ++ lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey; ++ } + /* If use extend FIFO mode */ + if (pScrn->currentMode->HDisplay > 1024) { + dwUseExtendedFIFO = 1; +@@ -1436,7 +1310,8 @@ + && (pPriv->old_src_w == src_w) && (pPriv->old_src_h == src_h) + && (pVia->old_dwUseExtendedFIFO == dwUseExtendedFIFO) + && (pVia->VideoStatus & VIDEO_SWOV_ON) && +- RegionsEqual(&pPriv->clip, clipBoxes)) { ++ REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { ++ DBG_DD(ErrorF(" via_video.c : don't do UpdateOverlay! \n")); + viaXvError(pScrn, pPriv, xve_none); + return Success; + } +@@ -1454,16 +1329,18 @@ + pVia->VideoStatus |= VIDEO_SWOV_ON; + + /* BitBlt: Draw the colorkey rectangle */ +- if (!RegionsEqual(&pPriv->clip, clipBoxes)) { ++ if (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); + if (pPriv->autoPaint) { + if (pDraw->type == DRAWABLE_WINDOW) { +- viaPaintColorkey(pScrn, pPriv, clipBoxes, pDraw); ++ xf86XVFillKeyHelperDrawable(pDraw, pPriv->colorKey, clipBoxes); ++ DamageDamageRegion(pDraw, clipBoxes); + } else { +- xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, +- clipBoxes); ++ xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } + } ++ } else { ++ DBG_DD(ErrorF(" via_video.c : // No need to draw Colorkey!! \n")); + } + /* + * Update video overlay +@@ -1498,6 +1375,7 @@ + + DBG_DD(ErrorF(" via_video.c : viaQueryImageAttributes : FourCC=0x%x, ", + id)); ++ DBG_DD(ErrorF(" via_video.c : Screen[%d], w=%d, h=%d\n", pScrn->scrnIndex, *w, *h)); + + if ((!w) || (!h)) + return 0; +Index: src/via_lvds.c +=================================================================== +--- src/via_lvds.c (revision 811) ++++ src/via_lvds.c (working copy) +@@ -42,7 +42,7 @@ + 2^13 X 0.0698uSec [1/14.318MHz] = 8192 X 0.0698uSec =572.1uSec + Timer = Counter x 572 uSec + 2. Note: +- 0.0698 uSec is too small to compute for hardware. So we multify a ++ 0.0698 uSec is too small to compute for hardware. So we multiply a + reference value(2^13) to make it big enough to compute for hardware. + 3. Note: + The meaning of the TD0~TD3 are count of the clock. +Index: src/via_video.h +=================================================================== +--- src/via_video.h (revision 811) ++++ src/via_video.h (working copy) +@@ -44,6 +44,10 @@ + + #define VIDEO_BPP 2 + ++ ++#define V1_COMMAND_FIRE 0x80000000 /* V1 commands fire */ ++#define V3_COMMAND_FIRE 0x40000000 /* V3 commands fire */ ++ + typedef struct + { + CARD32 interruptflag; /* 200 */ +@@ -89,7 +93,7 @@ + CARD32 video3_ctl; /* 2a0 */ + CARD32 video3_addr0; /* 2a4 */ + CARD32 video3_addr1; /* 2a8 */ +- CARD32 video3_stribe; /* 2ac */ ++ CARD32 video3_stride; /* 2ac */ + CARD32 video3_hvstart; /* 2b0 */ + CARD32 video3_size; /* 2b4 */ + CARD32 v3alpha_fetch; /* 2b8 */ +Index: src/via_mode.c +=================================================================== +--- src/via_mode.c (revision 811) ++++ src/via_mode.c (working copy) +@@ -308,11 +308,14 @@ + xf86MonPtr monPtr = NULL; + + if (pVia->pI2CBus2) +- monPtr = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus2); ++ monPtr = xf86DoEEDID(pScrn->scrnIndex, pVia->pI2CBus2, TRUE); + + if (monPtr) { + xf86PrintEDID(monPtr); + xf86SetDDCproperties(pScrn, monPtr); ++ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ++ "DDC pI2CBus2 detected a %s\n", DIGITAL(monPtr->features.input_type) ? ++ "DFP" : "CRT")); + return TRUE; + } else { + return FALSE; +@@ -380,6 +383,7 @@ + case VIA_CX700: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (ViaDFPDetect(pScrn)) { + pBIOSInfo->DfpPresent = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, +@@ -514,6 +518,7 @@ + case VIA_CX700: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + pVia->pBIOSInfo->Lvds->IsActive = TRUE ; + break; + } +@@ -859,6 +864,9 @@ + case VIA_MEM_DDR533: + case VIA_MEM_DDR667: + return VIA_BW_DDR667; ++ case VIA_MEM_DDR800: ++ case VIA_MEM_DDR1066: ++ return VIA_BW_DDR1066; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ViaBandwidthAllowed: Unknown memory type: %d\n", pVia->MemClk); +@@ -999,8 +1007,8 @@ + dn = pll.params.dn; + dm = pll.params.dm; + +- /* The VX855 does not modify dm/dn, but earlier chipsets do. */ +- if (pVia->Chipset != VIA_VX855) { ++ /* The VX855 and VX900 do not modify dm/dn, but earlier chipsets do. */ ++ if ((pVia->Chipset != VIA_VX855) && (pVia->Chipset != VIA_VX900)) { + dm -= 2; + dn -= 2; + } +@@ -1078,7 +1086,7 @@ + pBIOSInfo->Clock = Table.InitTb.LCDClk_12Bit; + else { + pBIOSInfo->Clock = Table.InitTb.VClk_12Bit; +- /* for some reason still to be defined this is neccessary */ ++ /* for some reason still to be defined this is necessary */ + ViaSetSecondaryDotclock(pScrn, Table.InitTb.LCDClk_12Bit); + } + } else { +@@ -1708,7 +1716,7 @@ + ViaModeSecondCRTC(pScrn, mode); + ViaSecondDisplayChannelEnable(pScrn); + } +- ++ + if (pBIOSInfo->FirstCRTC->IsActive) { + if (pBIOSInfo->CrtActive) { + /* CRT on FirstCRTC */ +@@ -1734,6 +1742,15 @@ + ViaDisplayDisableCRT(pScrn); + } + ++ // Enable panel support on VM800, K8M800 and VX900 chipset ++ // See: https://bugs.launchpad.net/openchrome/+bug/186103 ++ if (pBIOSInfo->Panel->IsActive && ++ ((pVia->Chipset == VIA_VM800) || ++ (pVia->Chipset == VIA_K8M800) || ++ (pVia->Chipset == VIA_VX900) )) { ++ pBIOSInfo->FirstCRTC->IsActive=TRUE; ++ ViaModeFirstCRTC(pScrn, mode); ++ } + if (pBIOSInfo->Simultaneous->IsActive) { + ViaDisplayEnableSimultaneous(pScrn); + } else { +Index: src/via_mode.h +=================================================================== +--- src/via_mode.h (revision 811) ++++ src/via_mode.h (working copy) +@@ -32,8 +32,9 @@ + */ + #define VIA_BW_MIN 74000000 /* > 640x480@60Hz@32bpp */ + #define VIA_BW_DDR200 394000000 +-#define VIA_BW_DDR400 498000000 /* > 1920x1080@60Hz@32bpp */ ++#define VIA_BW_DDR400 553000000 /* > 1920x1200@60Hz@32bpp */ + #define VIA_BW_DDR667 922000000 ++#define VIA_BW_DDR1066 922000000 + + union pllparams { + struct { +@@ -54,50 +55,50 @@ + CARD16 UniChrome; + union pllparams UniChromePro; + } ViaDotClocks[] = { +- { 25200, 0x513C, /* 0xa79004 */ { 1, 4, 6, 169 } }, +- { 25312, 0xC763, /* 0xc49005 */ { 1, 4, 7, 198 } }, +- { 26591, 0x471A, /* 0xce9005 */ { 1, 4, 7, 208 } }, +- { 31500, 0xC558, /* 0xae9003 */ { 1, 4, 5, 176 } }, +- { 31704, 0x471F, /* 0xaf9002 */ { 1, 4, 4, 177 } }, +- { 32663, 0xC449, /* 0x479000 */ { 1, 4, 2, 73 } }, +- { 33750, 0x4721, /* 0x959002 */ { 1, 4, 4, 151 } }, +- { 35500, 0x5877, /* 0x759001 */ { 1, 4, 3, 119 } }, +- { 36000, 0x5879, /* 0x9f9002 */ { 1, 4, 4, 161 } }, +- { 39822, 0xC459, /* 0x578c02 */ { 1, 3, 4, 89 } }, +- { 40000, 0x515F, /* 0x848c04 */ { 1, 3, 6, 134 } }, +- { 41164, 0x4417, /* 0x2c8c00 */ { 1, 3, 2, 46 } }, +- { 46981, 0x5069, /* 0x678c02 */ { 1, 3, 4, 105 } }, +- { 49500, 0xC353, /* 0xa48c04 */ { 3, 3, 5, 138 } }, +- { 50000, 0xC354, /* 0x368c00 */ { 1, 3, 2, 56 } }, +- { 56300, 0x4F76, /* 0x3d8c00 */ { 1, 3, 2, 63 } }, +- { 57275, 0, /* 0x3e8c00 */ { 1, 3, 5, 157 } }, /* For XO 1.5 no need for a unichrome clock */ +- { 57284, 0x4E70, /* 0x3e8c00 */ { 1, 3, 2, 64 } }, +- { 64995, 0x0D3B, /* 0x6b8c01 */ { 1, 3, 3, 109 } }, +- { 65000, 0x0D3B, /* 0x6b8c01 */ { 1, 3, 3, 109 } }, /* Slightly unstable on PM800 */ +- { 65028, 0x866D, /* 0x6b8c01 */ { 1, 3, 3, 109 } }, +- { 74480, 0x156E, /* 0x288800 */ { 1, 2, 2, 42 } }, +- { 75000, 0x156E, /* 0x288800 */ { 1, 2, 2, 42 } }, +- { 78800, 0x442C, /* 0x2a8800 */ { 1, 2, 2, 44 } }, +- { 81135, 0x0622, /* 0x428801 */ { 1, 2, 3, 68 } }, +- { 81613, 0x4539, /* 0x708803 */ { 1, 2, 5, 114 } }, +- { 94500, 0x4542, /* 0x4d8801 */ { 1, 2, 3, 79 } }, +- { 108000, 0x0B53, /* 0x778802 */ { 1, 2, 4, 121 } }, +- { 108280, 0x4879, /* 0x778802 */ { 1, 2, 4, 121 } }, +- { 122000, 0x0D6F, /* 0x428800 */ { 1, 2, 2, 68 } }, +- { 122726, 0x073C, /* 0x878802 */ { 1, 2, 4, 137 } }, +- { 135000, 0x0742, /* 0x6f8801 */ { 1, 2, 3, 113 } }, +- { 148500, 0x0853, /* 0x518800 */ { 1, 2, 2, 83 } }, +- { 155800, 0x0857, /* 0x558402 */ { 1, 1, 4, 87 } }, +- { 157500, 0x422C, /* 0x2a8400 */ { 1, 1, 2, 44 } }, +- { 161793, 0x4571, /* 0x6f8403 */ { 1, 1, 5, 113 } }, +- { 162000, 0x0A71, /* 0x6f8403 */ { 1, 1, 5, 113 } }, +- { 175500, 0x4231, /* 0x2f8400 */ { 1, 1, 2, 49 } }, +- { 189000, 0x0542, /* 0x4d8401 */ { 1, 1, 3, 79 } }, +- { 202500, 0x0763, /* 0x6F8402 */ { 1, 1, 4, 113 } }, +- { 204800, 0x0764, /* 0x548401 */ { 1, 1, 3, 86 } }, +- { 218300, 0x043D, /* 0x3b8400 */ { 1, 1, 2, 61 } }, +- { 229500, 0x0660, /* 0x3e8400 */ { 1, 1, 2, 64 } }, /* Not tested on Pro } */ +- { 0, 0, { 0, 0, 0, 0 } } ++ { 25200, 0x513C, /* 0xa79004 */ { { 1, 4, 6, 169 } } }, ++ { 25312, 0xC763, /* 0xc49005 */ { { 1, 4, 7, 198 } } }, ++ { 26591, 0x471A, /* 0xce9005 */ { { 1, 4, 7, 208 } } }, ++ { 31500, 0xC558, /* 0xae9003 */ { { 1, 4, 5, 176 } } }, ++ { 31704, 0x471F, /* 0xaf9002 */ { { 1, 4, 4, 177 } } }, ++ { 32663, 0xC449, /* 0x479000 */ { { 1, 4, 2, 73 } } }, ++ { 33750, 0x4721, /* 0x959002 */ { { 1, 4, 4, 151 } } }, ++ { 35500, 0x5877, /* 0x759001 */ { { 1, 4, 3, 119 } } }, ++ { 36000, 0x5879, /* 0x9f9002 */ { { 1, 4, 4, 161 } } }, ++ { 39822, 0xC459, /* 0x578c02 */ { { 1, 3, 4, 89 } } }, ++ { 40000, 0x515F, /* 0x848c04 */ { { 1, 3, 6, 134 } } }, ++ { 41164, 0x4417, /* 0x2c8c00 */ { { 1, 3, 2, 46 } } }, ++ { 46981, 0x5069, /* 0x678c02 */ { { 1, 3, 4, 105 } } }, ++ { 49500, 0xC353, /* 0xa48c04 */ { { 3, 3, 5, 138 } } }, ++ { 50000, 0xC354, /* 0x368c00 */ { { 1, 3, 2, 56 } } }, ++ { 56300, 0x4F76, /* 0x3d8c00 */ { { 1, 3, 2, 63 } } }, ++ { 57275, 0, /* 0x3e8c00 */ { { 1, 3, 5, 157 } } }, /* For XO 1.5 no need for a unichrome clock */ ++ { 57284, 0x4E70, /* 0x3e8c00 */ { { 1, 3, 2, 64 } } }, ++ { 64995, 0x0D3B, /* 0x6b8c01 */ { { 1, 3, 3, 109 } } }, ++ { 65000, 0x0D3B, /* 0x6b8c01 */ { { 1, 3, 3, 109 } } }, /* Slightly unstable on PM800 */ ++ { 65028, 0x866D, /* 0x6b8c01 */ { { 1, 3, 3, 109 } } }, ++ { 74480, 0x156E, /* 0x288800 */ { { 1, 2, 2, 42 } } }, ++ { 75000, 0x156E, /* 0x288800 */ { { 1, 2, 2, 42 } } }, ++ { 78800, 0x442C, /* 0x2a8800 */ { { 1, 2, 2, 44 } } }, ++ { 81135, 0x0622, /* 0x428801 */ { { 1, 2, 3, 68 } } }, ++ { 81613, 0x4539, /* 0x708803 */ { { 1, 2, 5, 114 } } }, ++ { 94500, 0x4542, /* 0x4d8801 */ { { 1, 2, 3, 79 } } }, ++ { 108000, 0x0B53, /* 0x778802 */ { { 1, 2, 4, 121 } } }, ++ { 108280, 0x4879, /* 0x778802 */ { { 1, 2, 4, 121 } } }, ++ { 122000, 0x0D6F, /* 0x428800 */ { { 1, 2, 2, 68 } } }, ++ { 122726, 0x073C, /* 0x878802 */ { { 1, 2, 4, 137 } } }, ++ { 135000, 0x0742, /* 0x6f8801 */ { { 1, 2, 3, 113 } } }, ++ { 148500, 0x0853, /* 0x518800 */ { { 1, 2, 2, 83 } } }, ++ { 155800, 0x0857, /* 0x558402 */ { { 1, 1, 4, 87 } } }, ++ { 157500, 0x422C, /* 0x2a8400 */ { { 1, 1, 2, 44 } } }, ++ { 161793, 0x4571, /* 0x6f8403 */ { { 1, 1, 5, 113 } } }, ++ { 162000, 0x0A71, /* 0x6f8403 */ { { 1, 1, 5, 113 } } }, ++ { 175500, 0x4231, /* 0x2f8400 */ { { 1, 1, 2, 49 } } }, ++ { 189000, 0x0542, /* 0x4d8401 */ { { 1, 1, 3, 79 } } }, ++ { 202500, 0x0763, /* 0x6F8402 */ { { 1, 1, 4, 113 } } }, ++ { 204800, 0x0764, /* 0x548401 */ { { 1, 1, 3, 86 } } }, ++ { 218300, 0x043D, /* 0x3b8400 */ { { 1, 1, 2, 61 } } }, ++ { 229500, 0x0660, /* 0x3e8400 */ { { 1, 1, 2, 64 } } }, /* Not tested on Pro } */ ++ { 0, 0, { { 0, 0, 0, 0 } } } + }; + + /* +@@ -131,7 +132,7 @@ + { MODEPREFIX("856x480"), 31704, 856, 872, 960, 1064, 0, 480, 480, 483, 497, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1024x512"), 41164, 1024, 1056, 1160, 1296, 0, 512, 512, 515, 531, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1024x576"), 46981, 1024, 1064, 1168, 1312, 0, 576, 576, 579, 597, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, +- { MODEPREFIX("1024x600"), 48960, 1024, 1064, 1168, 1312, 0, 600, 601, 604, 622, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, ++ { MODEPREFIX("1024x600"), 48960, 1024, 1048, 1152, 1312, 0, 600, 601, 604, 630, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1024x768"), 65028, 1024, 1048, 1184, 1344, 0, 768, 770, 776, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, + { MODEPREFIX("1152x864"), 81613, 1152, 1216, 1336, 1520, 0, 864, 864, 867, 895, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, + { MODEPREFIX("1280x768"), 81135, 1280, 1328, 1440, 1688, 0, 768, 770, 776, 802, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, +Index: src/via_memcpy.c +=================================================================== +--- src/via_memcpy.c (revision 811) ++++ src/via_memcpy.c (working copy) +@@ -581,12 +581,12 @@ + + if (VIAAllocLinear(&tmpFbBuffer, pScrn, alignSize + 31)) + return libc_YUV42X; +- if (NULL == (buf2 = (unsigned char *)xalloc(testSize))) { ++ if (NULL == (buf2 = (unsigned char *)malloc(testSize))) { + VIAFreeLinear(&tmpFbBuffer); + return libc_YUV42X; + } +- if (NULL == (buf3 = (unsigned char *)xalloc(testSize))) { +- xfree(buf2); ++ if (NULL == (buf3 = (unsigned char *)malloc(testSize))) { ++ free(buf2); + VIAFreeLinear(&tmpFbBuffer); + return libc_YUV42X; + } +@@ -642,8 +642,8 @@ + curData->mName); + } + } +- xfree(buf3); +- xfree(buf2); ++ free(buf3); ++ free(buf2); + VIAFreeLinear(&tmpFbBuffer); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Using %s YUV42X copy for %s.\n", +Index: src/via_driver.c +=================================================================== +--- src/via_driver.c (revision 811) ++++ src/via_driver.c (working copy) +@@ -143,6 +143,7 @@ + VIA_DEVICE_MATCH (PCI_CHIP_VT3327, 0 ), + VIA_DEVICE_MATCH (PCI_CHIP_VT3353, 0 ), + VIA_DEVICE_MATCH (PCI_CHIP_VT3409, 0 ), ++ VIA_DEVICE_MATCH (PCI_CHIP_VT3410, 0 ), + { 0, 0, 0 }, + }; + +@@ -174,12 +175,13 @@ + {VIA_K8M800, "K8M800/K8N800"}, + {VIA_PM800, "PM800/PM880/CN400"}, + {VIA_VM800, "VM800/P4M800Pro/VN800/CN700"}, ++ {VIA_CX700, "CX700/VX700"}, + {VIA_K8M890, "K8M890/K8N890"}, ++ {VIA_P4M890, "P4M890"}, + {VIA_P4M900, "P4M900/VN896/CN896"}, +- {VIA_CX700, "CX700/VX700"}, +- {VIA_P4M890, "P4M890"}, +- {VIA_VX800, "VX800"}, +- {VIA_VX855, "VX855"}, ++ {VIA_VX800, "VX800/VX820"}, ++ {VIA_VX855, "VX855/VX875"}, ++ {VIA_VX900, "VX900"}, + {-1, NULL } + }; + +@@ -190,12 +192,13 @@ + {VIA_K8M800, PCI_CHIP_VT3204, VIA_RES_SHARED}, + {VIA_PM800, PCI_CHIP_VT3259, VIA_RES_SHARED}, + {VIA_VM800, PCI_CHIP_VT3314, VIA_RES_SHARED}, ++ {VIA_CX700, PCI_CHIP_VT3324, VIA_RES_SHARED}, + {VIA_K8M890, PCI_CHIP_VT3336, VIA_RES_SHARED}, ++ {VIA_P4M890, PCI_CHIP_VT3327, VIA_RES_SHARED}, + {VIA_P4M900, PCI_CHIP_VT3364, VIA_RES_SHARED}, +- {VIA_CX700, PCI_CHIP_VT3324, VIA_RES_SHARED}, +- {VIA_P4M890, PCI_CHIP_VT3327, VIA_RES_SHARED}, + {VIA_VX800, PCI_CHIP_VT3353, VIA_RES_SHARED}, + {VIA_VX855, PCI_CHIP_VT3409, VIA_RES_SHARED}, ++ {VIA_VX900, PCI_CHIP_VT3410, VIA_RES_SHARED}, + {-1, -1, VIA_RES_UNDEF} + }; + +@@ -215,9 +218,11 @@ + OPTION_EXA_SCRATCH_SIZE, + OPTION_SWCURSOR, + OPTION_SHADOW_FB, ++ OPTION_ROTATION_TYPE, + OPTION_ROTATE, + OPTION_VIDEORAM, + OPTION_ACTIVEDEVICE, ++ OPTION_I2CDEVICES, + OPTION_BUSWIDTH, + OPTION_CENTER, + OPTION_PANELSIZE, +@@ -253,6 +258,7 @@ + {OPTION_EXA_SCRATCH_SIZE, "ExaScratchSize", OPTV_INTEGER, {0}, FALSE}, + {OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, ++ {OPTION_ROTATION_TYPE, "RotationType", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_VIDEORAM, "VideoRAM", OPTV_INTEGER, {0}, FALSE}, + {OPTION_ACTIVEDEVICE, "ActiveDevice", OPTV_ANYSTR, {0}, FALSE}, +@@ -276,6 +282,7 @@ + {OPTION_MODE_SWITCH_METHOD, "ModeSwitchMethod", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_MAX_DRIMEM, "MaxDRIMem", OPTV_INTEGER, {0}, FALSE}, + {OPTION_AGPMEM, "AGPMem", OPTV_INTEGER, {0}, FALSE}, ++ {OPTION_I2CDEVICES, "I2CDevices", OPTV_ANYSTR, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} + }; + +@@ -307,6 +314,7 @@ + { + static Bool setupDone = FALSE; + ++ /* Only be loaded once */ + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&VIA, module, +@@ -339,6 +347,7 @@ + if (pScrn->driverPrivate) + return TRUE; + ++ /* allocate VIARec */ + pScrn->driverPrivate = xnfcalloc(sizeof(VIARec), 1); + VIAPtr pVia = ((VIARec *) (pScrn->driverPrivate)); + +@@ -400,36 +409,36 @@ + + if (pBIOSInfo->Panel) { + if (pBIOSInfo->Panel->NativeMode) +- xfree(pBIOSInfo->Panel->NativeMode); ++ free(pBIOSInfo->Panel->NativeMode); + if (pBIOSInfo->Panel->CenteredMode) +- xfree(pBIOSInfo->Panel->CenteredMode); +- xfree(pBIOSInfo->Panel); ++ free(pBIOSInfo->Panel->CenteredMode); ++ free(pBIOSInfo->Panel); + } + + if (pBIOSInfo->FirstCRTC) +- xfree(pBIOSInfo->FirstCRTC); ++ free(pBIOSInfo->FirstCRTC); + if (pBIOSInfo->SecondCRTC) +- xfree(pBIOSInfo->SecondCRTC); ++ free(pBIOSInfo->SecondCRTC); + if (pBIOSInfo->Simultaneous) +- xfree(pBIOSInfo->Simultaneous); ++ free(pBIOSInfo->Simultaneous); + if (pBIOSInfo->Lvds) +- xfree(pBIOSInfo->Lvds); ++ free(pBIOSInfo->Lvds); + } + + if (VIAPTR(pScrn)->pVbe) + vbeFree(VIAPTR(pScrn)->pVbe); + + if (pVia->VideoRegs) +- xfree(pVia->VideoRegs); ++ free(pVia->VideoRegs); + + if (((VIARec *) (pScrn->driverPrivate))->pBIOSInfo->TVI2CDev) + xf86DestroyI2CDevRec((((VIARec *) (pScrn->driverPrivate))->pBIOSInfo-> + TVI2CDev), TRUE); +- xfree(((VIARec *) (pScrn->driverPrivate))->pBIOSInfo); ++ free(((VIARec *) (pScrn->driverPrivate))->pBIOSInfo); + + VIAUnmapMem(pScrn); + +- xfree(pScrn->driverPrivate); ++ free(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + } /* VIAFreeRec */ + +@@ -455,7 +464,6 @@ + { + ScrnInfoPtr scrn = NULL; + EntityInfoPtr entity; +- DevUnion *private; + + scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VIAPciChipsets, + NULL, NULL, NULL, NULL, NULL); +@@ -513,7 +521,7 @@ + numDevSections, + drv, + &usedChips); +- xfree(devSections); ++ free(devSections); + + if (numUsed <= 0) + return FALSE; +@@ -588,11 +596,11 @@ + } + instance++; + } +- xfree(pEnt); ++ free(pEnt); + } + } + +- xfree(usedChips); ++ free(usedChips); + + return foundScreen; + +@@ -652,6 +660,12 @@ + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrn, "vbe")) { ++ /* FIXME This line should be replaced with: ++ ++ pVbe = VBEExtendedInit(NULL, index, 0); ++ ++ for XF86 version > 4.2.99 ++ */ + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); +@@ -664,7 +678,7 @@ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + +- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetupDefaultOptions\n")); ++ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetupDefaultOptions - Setting up default chipset options.\n")); + + pVia->shadowFB = FALSE; + pVia->NoAccel = FALSE; +@@ -684,10 +698,14 @@ + pVia->maxDriSize = 0; + pVia->agpMem = AGP_SIZE / 1024; + pVia->ActiveDevice = 0x00; ++ pVia->I2CDevices = 0x00; + pVia->VideoEngine = VIDEO_ENGINE_CLE; + #ifdef HAVE_DEBUG + pVia->PrintVGARegs = FALSE; + #endif ++ ++ /* Disable vertical interpolation because the size of */ ++ /* line buffer (limited to 800) is too small to do interpolation. */ + pVia->swov.maxWInterp = 800; + pVia->swov.maxHInterp = 600; + pVia->useLegacyVBE = TRUE; +@@ -710,20 +728,30 @@ + break; + case VIA_K8M800: + pVia->DRIIrqEnable = FALSE; +- pVia->UseLegacyModeSwitch = TRUE; + break; + case VIA_PM800: ++ /* Use new mode switch to resolve many resolution and display bugs (switch to console) */ ++ /* FIXME The video playing (XV) is not working correctly after turn on new mode switch */ + pVia->VideoEngine = VIDEO_ENGINE_CME; +- pVia->UseLegacyModeSwitch = TRUE; + break; + case VIA_VM800: +- pVia->UseLegacyModeSwitch = TRUE; ++ /* New mode switch resolve bug with gamma set #282 */ ++ /* and with Xv after hibernate #240 */ + break; ++ case VIA_CX700: ++ pVia->VideoEngine = VIDEO_ENGINE_CME; ++ pVia->swov.maxWInterp = 1920; ++ pVia->swov.maxHInterp = 1080; ++ break; + case VIA_K8M890: + pVia->VideoEngine = VIDEO_ENGINE_CME; + pVia->agpEnable = FALSE; + pVia->dmaXV = FALSE; + break; ++ case VIA_P4M890: ++ pVia->VideoEngine = VIDEO_ENGINE_CME; ++ pVia->dmaXV = FALSE; ++ break; + case VIA_P4M900: + pVia->VideoEngine = VIDEO_ENGINE_CME; + pVia->agpEnable = FALSE; +@@ -732,20 +760,13 @@ + pVia->dmaXV = FALSE; + pBIOSInfo->TVDIPort = VIA_DI_PORT_DVP0; + break; +- case VIA_CX700: +- pVia->VideoEngine = VIDEO_ENGINE_CME; +- pVia->swov.maxWInterp = 1920; +- pVia->swov.maxHInterp = 1080; +- break; +- case VIA_P4M890: +- pVia->VideoEngine = VIDEO_ENGINE_CME; +- pVia->dmaXV = FALSE; +- break; ++ + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + pVia->VideoEngine = VIDEO_ENGINE_CME; +- /* pVia->agpEnable = FALSE; +- pVia->dmaXV = FALSE;*/ ++ pVia->agpEnable = FALSE; ++ pVia->dmaXV = FALSE; + break; + } + +@@ -807,7 +828,7 @@ + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + #ifndef XSERVER_LIBPCIACCESS + if (pEnt->resources) { +- xfree(pEnt); ++ free(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } +@@ -825,7 +846,7 @@ + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex); + pVIAEnt = pPriv->ptr; + if (pVIAEnt->BypassSecondary) { +- xfree(pEnt); ++ free(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } +@@ -848,6 +869,7 @@ + pVIAEnt->HasSecondary = FALSE; + pVIAEnt->RestorePrimary = FALSE; + pVIAEnt->IsSecondaryRestored = FALSE; ++ + } + } else { + pVia->sharedData = xnfcalloc(sizeof(ViaSharedRec), 1); +@@ -866,7 +888,7 @@ + */ + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { +- xfree(pEnt); ++ free(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } else { +@@ -881,7 +903,7 @@ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); +- xfree(pEnt); ++ free(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } +@@ -897,7 +919,7 @@ + rgb zeros = { 0, 0, 0 }; + + if (!xf86SetWeight(pScrn, zeros, zeros)) { +- xfree(pEnt); ++ free(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } else { +@@ -914,7 +936,7 @@ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported at depth %d.\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); +- xfree(pEnt); ++ free(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } +@@ -979,7 +1001,7 @@ + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset revision: %d\n", pVia->ChipRev); + +- xfree(pEnt); ++ free(pEnt); + + /* Detect the amount of installed RAM */ + from = X_PROBED; +@@ -993,6 +1015,12 @@ + + switch (pVia->Chipset) { + case VIA_CLE266: ++#ifdef XSERVER_LIBPCIACCESS ++ pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); ++#else ++ videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; ++#endif ++ pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; + case VIA_KM400: + #ifdef XSERVER_LIBPCIACCESS + pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); +@@ -1000,6 +1028,12 @@ + videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; + #endif + pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; ++ /* Workaround for #177 (VRAM probing fail on P4M800) */ ++ if (pScrn->videoRam < 16384) { ++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, ++ "Memory size detection failed: using 16 MB.\n"); ++ pScrn->videoRam = 16 << 10; ++ } + break; + case VIA_PM800: + case VIA_VM800: +@@ -1017,6 +1051,7 @@ + case VIA_CX700: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + #ifdef XSERVER_LIBPCIACCESS + pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); + #else +@@ -1046,23 +1081,18 @@ + } + } + +- if (from == X_PROBED) ++ if (from == X_PROBED) { + xf86DrvMsg(pScrn->scrnIndex, from, + "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam); ++ } + +- xf86DrvMsg(pScrn->scrnIndex, X_INFO, +- "Setting up default chipset options.\n"); + if (!VIASetupDefaultOptions(pScrn)) { + VIAFreeRec(pScrn); + return FALSE; + } + +- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reading config file...\n"); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, VIAOptions); + +- xf86DrvMsg(pScrn->scrnIndex, X_INFO, +- "Starting to parse config file options...\n"); +- + if (xf86GetOptValInteger(VIAOptions, OPTION_VIDEORAM, &pScrn->videoRam)) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Setting amount of VideoRAM to %d kB\n", pScrn->videoRam); +@@ -1100,6 +1130,31 @@ + } + + /* When rotating, switch shadow framebuffer on and acceleration off. */ ++ if ((s = xf86GetOptValString(VIAOptions, OPTION_ROTATION_TYPE))) { ++ if (!xf86NameCmp(s, "SWRandR")) { ++ pVia->shadowFB = TRUE; ++ pVia->NoAccel = TRUE; ++ pVia->RandRRotation = TRUE; ++ pVia->rotate = RR_Rotate_0; ++ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen " ++ "RandR enabled, acceleration disabled\n"); ++ } else if (!xf86NameCmp(s, "HWRandR")) { ++ pVia->shadowFB = TRUE; ++ pVia->NoAccel = TRUE; ++ pVia->RandRRotation = TRUE; ++ pVia->rotate = RR_Rotate_0; ++ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Hardware accelerated " ++ "rotating screen is not implemented. Using SW RandR.\n"); ++ } else { ++ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" ++ "value for Option \"RotationType\".\n", s); ++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, ++ "Valid options are \"SWRandR\" and \"HWRandR\".\n"); ++ } ++ } ++ ++ ++ /* When rotating, switch shadow framebuffer on and acceleration off. */ + if ((s = xf86GetOptValString(VIAOptions, OPTION_ROTATE))) { + if (!xf86NameCmp(s, "CW")) { + pVia->shadowFB = TRUE; +@@ -1498,6 +1553,7 @@ + } + } + ++ /* Initialize the colormap */ + Gamma zeros = { 0.0, 0.0, 0.0 }; + if (!xf86SetGamma(pScrn, zeros)) { + VIAFreeRec(pScrn); +@@ -1523,6 +1579,17 @@ + + pVia->videoRambytes = pScrn->videoRam << 10; + ++ /* I2CDevices Option for I2C Initialization */ ++ //pVia->I2CDevices = 0x00; ++ if ((s = xf86GetOptValString(VIAOptions, OPTION_I2CDEVICES))) { ++ if (strstr(s, "Bus1")) ++ pVia->I2CDevices |= VIA_I2C_BUS1; ++ if (strstr(s, "Bus2")) ++ pVia->I2CDevices |= VIA_I2C_BUS2; ++ if (strstr(s, "Bus3")) ++ pVia->I2CDevices |= VIA_I2C_BUS3; ++ } ++ + if (!xf86LoadSubModule(pScrn, "i2c")) { + VIAFreeRec(pScrn); + return FALSE; +@@ -1536,10 +1603,13 @@ + } else { + + if (pVia->pI2CBus1) { +- pVia->DDC1 = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus1); ++ pVia->DDC1 = xf86DoEEDID(pScrn->scrnIndex, pVia->pI2CBus1, TRUE); + if (pVia->DDC1) { + xf86PrintEDID(pVia->DDC1); + xf86SetDDCproperties(pScrn, pVia->DDC1); ++ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ++ "DDC pI2CBus1 detected a %s\n", DIGITAL(pVia->DDC1->features.input_type) ? ++ "DFP" : "CRT")); + } + } + } +@@ -1559,17 +1629,6 @@ + ViaPanelPreInit(pScrn); + } + +- if (pBIOSInfo->Panel->IsActive && +- ((pVia->Chipset == VIA_K8M800) || +- (pVia->Chipset == VIA_PM800) || +- (pVia->Chipset == VIA_VM800))) { +- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Panel on K8M800, PM800 and " +- "VM800 is currently not supported.\n"); +- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, +- "Using VBE to set modes to work around this.\n"); +- pVia->useVBEModes = TRUE; +- } +- + pVia->pVbe = NULL; + if (pVia->useVBEModes) { + /* VBE doesn't properly initialise int10 itself. */ +@@ -1593,6 +1652,7 @@ + } + + } else { ++ int max_pitch, max_height; + /* Add own modes. */ + ViaModesAttach(pScrn, pScrn->monitor); + +@@ -1609,6 +1669,26 @@ + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = FALSE; + ++ switch (pVia->Chipset) { ++ case VIA_CLE266: ++ case VIA_KM400: ++ case VIA_K8M800: ++ case VIA_PM800: ++ case VIA_VM800: ++ max_pitch = 3344; ++ max_height = 2508; ++ case VIA_CX700: ++ case VIA_K8M890: ++ case VIA_P4M890: ++ case VIA_P4M900: ++ max_pitch = 8192/(pScrn->bitsPerPixel >> 3)-1; ++ max_height = max_pitch; ++ break; ++ default: ++ max_pitch = 16384/(pScrn->bitsPerPixel >> 3)-1; ++ max_height = max_pitch; ++ } ++ + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and +@@ -1621,7 +1701,7 @@ + * + * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited + * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1). +- * Test CLE266Cx, KM400, KM400A, K8M800, PM800, CN400 please. ++ * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please. + * + * We should be able to limit the memory available for a mode to 32 MB, + * but xf86ValidateModes (or miScanLineWidth) fails to catch this +@@ -1629,15 +1709,16 @@ + */ + + /* Select valid modes from those available. */ +- i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, /* availModes */ +- pScrn->display->modes, /* modeNames */ +- clockRanges, /* list of clock ranges */ ++ i = xf86ValidateModes(pScrn, ++ pScrn->monitor->Modes, /* List of modes available for the monitor */ ++ pScrn->display->modes, /* List of mode names that the screen is requesting */ ++ clockRanges, /* list of clock ranges */ + NULL, /* list of line pitches */ + 256, /* minimum line pitch */ +- 3344, /* maximum line pitch */ +- 32 * 8, /* pitch inc (bits) */ +- 128, /* min height */ +- 2508, /* max height */ ++ max_pitch, /* maximum line pitch */ ++ 16 * 8, /* pitch increment (in bits), we just want 16 bytes alignment */ ++ 128, /* min virtual height */ ++ max_height, /* maximum virtual height */ + pScrn->display->virtualX, /* virtual width */ + pScrn->display->virtualY, /* virtual height */ + pVia->videoRambytes, /* apertureSize */ +@@ -1650,6 +1731,7 @@ + return FALSE; + } + ++ /* This function deletes modes in the modes field of the ScrnInfoRec that have been marked as invalid. */ + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { +@@ -1662,9 +1744,17 @@ + /* Set up screen parameters. */ + pVia->Bpp = pScrn->bitsPerPixel >> 3; + pVia->Bpl = pScrn->displayWidth * pVia->Bpp; ++ ++ /* This function fills in the Crtc fields for all the modes in the modes field of the ScrnInfoRec. */ + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); ++ ++ /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; ++ ++ /* Print the list of modes being used */ + xf86PrintModes(pScrn); ++ ++ /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + #ifdef USE_FB +@@ -1822,6 +1912,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + break; + default: + hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40); +@@ -1935,7 +2026,9 @@ + Regs->SR17 = hwp->readSeq(hwp, 0x17); + Regs->SR18 = hwp->readSeq(hwp, 0x18); + Regs->SR19 = hwp->readSeq(hwp, 0x19); ++ /* PCI Bus Control */ + Regs->SR1A = hwp->readSeq(hwp, 0x1A); ++ + Regs->SR1B = hwp->readSeq(hwp, 0x1B); + Regs->SR1C = hwp->readSeq(hwp, 0x1C); + Regs->SR1D = hwp->readSeq(hwp, 0x1D); +@@ -1977,40 +2070,59 @@ + Regs->SR4C = hwp->readSeq(hwp, 0x4C); + break; + } +- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, +- "Non-Primary Adapter! saving VGA_SR_MODE only !!\n")); ++ ++ /* Save Preemptive Arbiter Control Register */ ++ Regs->SR4D = hwp->readSeq(hwp, 0x4D); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Crtc...\n")); + + Regs->CR13 = hwp->readCrtc(hwp, 0x13); + + Regs->CR32 = hwp->readCrtc(hwp, 0x32); + Regs->CR33 = hwp->readCrtc(hwp, 0x33); +- Regs->CR34 = hwp->readCrtc(hwp, 0x34); ++ + Regs->CR35 = hwp->readCrtc(hwp, 0x35); + Regs->CR36 = hwp->readCrtc(hwp, 0x36); + ++ ++ ++ /* Starting Address */ ++ /* Start Address High */ ++ Regs->CR0C = hwp->readCrtc(hwp, 0x0C); ++ /* Start Address Low */ ++ Regs->CR0D = hwp->readCrtc(hwp, 0x0D); ++ /* Starting Address Overflow Bits[28:24] */ + Regs->CR48 = hwp->readCrtc(hwp, 0x48); ++ /* CR34 are fire bits. Must be written after CR0C CR0D CR48. */ ++ /* Starting Address Overflow Bits[23:16] */ ++ Regs->CR34 = hwp->readCrtc(hwp, 0x34); ++ ++ + Regs->CR49 = hwp->readCrtc(hwp, 0x49); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TVSave...\n")); + if (pBIOSInfo->TVI2CDev) + ViaTVSave(pScrn); + +- /* Save LCD control registers. */ ++ /* Save LCD control registers (from CR 0x50 to 0x93). */ + for (i = 0; i < 68; i++) + Regs->CRTCRegs[i] = hwp->readCrtc(hwp, i + 0x50); + + if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) { +- +- Regs->CRA0 = hwp->readCrtc(hwp, 0xA0); +- Regs->CRA1 = hwp->readCrtc(hwp, 0xA1); +- Regs->CRA2 = hwp->readCrtc(hwp, 0xA2); +- ++ /* LVDS Channel 2 Function Select 0 / DVI Function Select */ + Regs->CR97 = hwp->readCrtc(hwp, 0x97); ++ /* LVDS Channel 1 Function Select 0 */ + Regs->CR99 = hwp->readCrtc(hwp, 0x99); ++ /* Digital Video Port 1 Function Select 0 */ + Regs->CR9B = hwp->readCrtc(hwp, 0x9B); ++ /* Power Now Control 4 */ + Regs->CR9F = hwp->readCrtc(hwp, 0x9F); + ++ /* Horizontal Scaling Initial Value */ ++ Regs->CRA0 = hwp->readCrtc(hwp, 0xA0); ++ /* Vertical Scaling Initial Value */ ++ Regs->CRA1 = hwp->readCrtc(hwp, 0xA1); ++ /* Scaling Enable Bit */ ++ Regs->CRA2 = hwp->readCrtc(hwp, 0xA2); + } + + /* Save TMDS status */ +@@ -2018,6 +2130,7 @@ + case VIA_CX700: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + Regs->CRD2 = hwp->readCrtc(hwp, 0xD2); + break; + } +@@ -2045,15 +2158,15 @@ + /* Unlock extended registers. */ + hwp->writeSeq(hwp, 0x10, 0x01); + +- /*=* CR6A, CR6B, CR6C must be reset before restore +- standard vga regs, or system will be hang. *=*/ ++ /*=* CR6A, CR6B, CR6C must be reset before restoring ++ standard vga regs, or system will hang. *=*/ + /*=* TODO Check is reset IGA2 channel before disable IGA2 channel +- is neccesery or it may cause some line garbage. *=*/ ++ is necessary or it may cause some line garbage. *=*/ + hwp->writeCrtc(hwp, 0x6A, 0x00); + hwp->writeCrtc(hwp, 0x6B, 0x00); + hwp->writeCrtc(hwp, 0x6C, 0x00); + +- /* Gamma must disable before restore pallette */ ++ /* Gamma must be disabled before restoring palette */ + ViaGammaDisable(pScrn); + + if (pBIOSInfo->TVI2CDev) +@@ -2098,11 +2211,19 @@ + hwp->writeSeq(hwp, 0x45, Regs->SR45); + hwp->writeSeq(hwp, 0x46, Regs->SR46); + ++ /* Reset VCK PLL */ ++ hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x02); /* Set SR40[1] to 1 */ ++ hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & 0xFD); /* Set SR40[1] to 0 */ ++ + /* ECK Clock Synthesizer: */ + hwp->writeSeq(hwp, 0x47, Regs->SR47); + hwp->writeSeq(hwp, 0x48, Regs->SR48); + hwp->writeSeq(hwp, 0x49, Regs->SR49); + ++ /* Reset ECK PLL */ ++ hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x01); /* Set SR40[0] to 1 */ ++ hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & 0xFE); /* Set SR40[0] to 0 */ ++ + switch (pVia->Chipset) { + case VIA_CLE266: + case VIA_KM400: +@@ -2112,9 +2233,22 @@ + hwp->writeSeq(hwp, 0x4A, Regs->SR4A); + hwp->writeSeq(hwp, 0x4B, Regs->SR4B); + hwp->writeSeq(hwp, 0x4C, Regs->SR4C); ++ ++ /* Reset LCK PLL */ ++ hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x04); /* Set SR40[2] to 1 */ ++ hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & 0xFB); /* Set SR40[2] to 0 */ + break; + } + ++ /* Restore Preemptive Arbiter Control Register ++ * VX800 and VX855 should restore this register too, ++ * but I don't do that for I don't want to affect any ++ * chips now. ++ */ ++ if (pVia->Chipset == VIA_VX900) { ++ hwp->writeSeq(hwp, 0x4D, Regs->SR4D); ++ } ++ + /* Reset dotclocks. */ + ViaSeqMask(hwp, 0x40, 0x06, 0x06); + ViaSeqMask(hwp, 0x40, 0x00, 0x06); +@@ -2127,14 +2261,23 @@ + hwp->writeCrtc(hwp, 0x32, Regs->CR32); + /* HSYNCH Adjuster */ + hwp->writeCrtc(hwp, 0x33, Regs->CR33); +- /* Starting Address Overflow */ +- hwp->writeCrtc(hwp, 0x34, Regs->CR34); + /* Extended Overflow */ + hwp->writeCrtc(hwp, 0x35, Regs->CR35); + /*Power Management 3 (Monitor Control) */ + hwp->writeCrtc(hwp, 0x36, Regs->CR36); + ++ /* Starting Address */ ++ /* Start Address High */ ++ hwp->writeCrtc(hwp, 0x0C, Regs->CR0C); ++ /* Start Address Low */ ++ hwp->writeCrtc(hwp, 0x0D, Regs->CR0D); ++ /* Starting Address Overflow Bits[28:24] */ + hwp->writeCrtc(hwp, 0x48, Regs->CR48); ++ /* CR34 are fire bits. Must be written after CR0C CR0D CR48. */ ++ /* Starting Address Overflow Bits[23:16] */ ++ hwp->writeCrtc(hwp, 0x34, Regs->CR34); ++ ++ + hwp->writeCrtc(hwp, 0x49, Regs->CR49); + + /* Restore LCD control registers. */ +@@ -2160,6 +2303,7 @@ + case VIA_CX700: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + /* LVDS Control Register */ + hwp->writeCrtc(hwp, 0xD2, Regs->CRD2); + break; +@@ -2189,6 +2333,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + ViaSeqMask(hwp, 0x1A, 0x08, 0x08); + break; + default: +@@ -2212,6 +2357,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + ViaSeqMask(hwp, 0x1A, 0x00, 0x08); + break; + default: +@@ -2328,10 +2474,18 @@ + VIAPtr pVia = VIAPTR(pScrn); + + #ifdef XSERVER_LIBPCIACCESS +- pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr; ++ if (pVia->Chipset == VIA_VX900) { ++ pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr; ++ } else { ++ pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr; ++ } + int err; + #else +- pVia->FrameBufferBase = pVia->PciInfo->memBase[0]; ++ if (pVia->Chipset == VIA_VX900) { ++ pVia->FrameBufferBase = pVia->PciInfo->memBase[2]; ++ } else { ++ pVia->FrameBufferBase = pVia->PciInfo->memBase[0]; ++ } + #endif + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n")); +@@ -2453,7 +2607,6 @@ + VIALoadRgbLut(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, + VisualPtr pVisual) + { +- VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + + int i, j, index; +@@ -2844,7 +2997,7 @@ + + if (pVia->shadowFB) { + pVia->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); +- pVia->ShadowPtr = xalloc(pVia->ShadowPitch * shadowHeight); ++ pVia->ShadowPtr = malloc(pVia->ShadowPitch * shadowHeight); + displayWidth = pVia->ShadowPitch / (pScrn->bitsPerPixel >> 3); + FBStart = pVia->ShadowPtr; + } else { +@@ -2880,7 +3033,6 @@ + VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mode) + { + VIAPtr pVia = VIAPTR(pScrn); +- VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAWriteMode\n")); + +@@ -2917,6 +3069,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + /* + * Since we are using virtual, we need to adjust + * the offset to match the framebuffer alignment. +@@ -2963,6 +3116,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + break; + default : + hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40); +@@ -2986,11 +3140,11 @@ + + viaExitAccel(pScreen); + if (pVia->ShadowPtr) { +- xfree(pVia->ShadowPtr); ++ free(pVia->ShadowPtr); + pVia->ShadowPtr = NULL; + } + if (pVia->DGAModes) { +- xfree(pVia->DGAModes); ++ free(pVia->DGAModes); + pVia->DGAModes = NULL; + } + +@@ -3033,9 +3187,7 @@ + VIAAdjustFrame(int scrnIndex, int x, int y, int flags) + { + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +- vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); +- CARD32 Base; + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAAdjustFrame %dx%d\n", x, y)); + +@@ -3173,7 +3325,6 @@ + static void + VIADPMS(ScrnInfoPtr pScrn, int mode, int flags) + { +- vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + +Index: src/via_crtc.c +=================================================================== +--- src/via_crtc.c (revision 811) ++++ src/via_crtc.c (working copy) +@@ -174,6 +174,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + break; + default: + ViaSeqMask(hwp, 0x16, 0x08, 0xBF); +@@ -234,8 +235,8 @@ + /* Primary starting address -> 0x00, adjustframe does the rest */ + hwp->writeCrtc(hwp, 0x0C, 0x00); + hwp->writeCrtc(hwp, 0x0D, 0x00); ++ ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */ + hwp->writeCrtc(hwp, 0x34, 0x00); +- ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */ + + /* vertical sync start : 2047 */ + temp = mode->CrtcVSyncStart; +@@ -278,6 +279,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + break; + default: + /* some leftovers */ +@@ -314,6 +316,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + break; + default: + /* some leftovers */ +@@ -331,15 +334,20 @@ + CARD32 Base; + CARD32 tmp; + ++ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCSetStartingAddress\n")); ++ + Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); + Base = Base >> 1; + + hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); + hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); ++ /* FIXME The proper starting address for CR48 is 0x1F - Bits[28:24] */ ++ if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) ++ ViaCrtcMask(hwp, 0x48, Base >> 24, 0x0F); ++ /* CR34 are fire bits. Must be written after CR0C CR0D CR48. */ + hwp->writeCrtc(hwp, 0x34, (Base & 0xFF0000) >> 16); + +- if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) +- ViaCrtcMask(hwp, 0x48, Base >> 24, 0x0F); ++ + } + + void +@@ -434,6 +442,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + break; + default: + ViaSeqMask(hwp, 0x16, 0x08, 0xBF); +@@ -518,6 +527,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + break; + default: + /* some leftovers */ +Index: src/via_swov.c +=================================================================== +--- src/via_swov.c (revision 811) ++++ src/via_swov.c (working copy) +@@ -65,6 +65,31 @@ + #define IN_VIDEO_DISPLAY (*((unsigned long volatile *)(pVia->VidMapBase+V_FLAGS))&VBI_STATUS) + #define VIA_FIRETIMEOUT 40000 + ++enum HQV_CME_Regs { ++ HQV_SDO_CTRL1, ++ HQV_SDO_CTRL2, ++ HQV_SDO_CTRL3, ++ HQV_SDO_CTRL4 ++}; ++ ++/* register offsets for VT3553/VX800 */ ++static const unsigned hqv_cme_regs[] = { ++ [HQV_SDO_CTRL1] = HQV_SRC_DATA_OFFSET_CONTROL1, ++ [HQV_SDO_CTRL2] = HQV_SRC_DATA_OFFSET_CONTROL2, ++ [HQV_SDO_CTRL3] = HQV_SRC_DATA_OFFSET_CONTROL3, ++ [HQV_SDO_CTRL4] = HQV_SRC_DATA_OFFSET_CONTROL4 ++}; ++ ++/* register hqv offsets for new VT3409/VX855 */ ++static const unsigned hqv_cme_regs_409[] = { ++ [HQV_SDO_CTRL1] = HQV_SRC_DATA_OFFSET_CTRL1_409, ++ [HQV_SDO_CTRL2] = HQV_SRC_DATA_OFFSET_CTRL2_409, ++ [HQV_SDO_CTRL3] = HQV_SRC_DATA_OFFSET_CTRL3_409, ++ [HQV_SDO_CTRL4] = HQV_SRC_DATA_OFFSET_CTRL4_409 ++}; ++ ++#define HQV_CME_REG(HWDiff, name) (HWDiff)->HQVCmeRegs[name] ++ + static void + viaWaitVideoCommandFire(VIAPtr pVia) + { +@@ -88,6 +113,7 @@ + { + unsigned long proReg = 0; + CARD32 volatile *pdwState; ++ unsigned count = 50000; + + if (pVia->ChipId == PCI_CHIP_VT3259 + && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) +@@ -96,10 +122,9 @@ + pdwState = (CARD32 volatile *)(pVia->VidMapBase + (HQV_CONTROL + proReg)); + + if (pVia->VideoEngine == VIDEO_ENGINE_CME) { +- // while (*pdwState & (HQV_SUBPIC_FLIP | HQV_SW_FLIP)) ; +- while (*pdwState & HQV_SUBPIC_FLIP); ++ while (--count && (*pdwState & HQV_SUBPIC_FLIP)); + } else { +- while (!(*pdwState & HQV_FLIP_STATUS)) ; ++ while (--count && !(*pdwState & HQV_FLIP_STATUS)) ; + } + } + +@@ -109,8 +134,9 @@ + CARD32 volatile *pdwState = + (CARD32 volatile *)(pVia->VidMapBase + HQV_CONTROL); + *pdwState = dwData; ++ unsigned count = 50000; + +- while ((*pdwState & HQV_FLIP_STATUS)) { ++ while (--count && (*pdwState & HQV_FLIP_STATUS)) { + VIDOutD(HQV_CONTROL, *pdwState | HQV_FLIP_STATUS); + } + } +@@ -126,6 +152,7 @@ + { + CARD32 volatile *pdwState; + unsigned long proReg = 0; ++ unsigned count = 50000; + + if (pVia->ChipId == PCI_CHIP_VT3259 + && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) +@@ -133,7 +160,7 @@ + + pdwState = (CARD32 volatile *)(pVia->VidMapBase + (HQV_CONTROL + proReg)); + if (pVia->swov.MPEG_ON) { +- while ((*pdwState & HQV_SW_FLIP)) ; ++ while (--count && (*pdwState & HQV_SW_FLIP)) ; + } + } + +@@ -179,12 +206,14 @@ + static void + SaveVideoRegister(VIAPtr pVia, CARD32 index, CARD32 data) + { ++ if (pVia->VidRegCursor >= VIDREG_BUFFER_SIZE) { ++ DBG_DD(ErrorF("SaveVideoRegister: Out of video register space flushing")); ++ FlushVidRegBuffer(pVia); ++ ResetVidRegBuffer(pVia); ++ } ++ + pVia->VidRegBuffer[pVia->VidRegCursor++] = index; + pVia->VidRegBuffer[pVia->VidRegCursor++] = data; +- +- if (pVia->VidRegCursor > VIDREG_BUFFER_SIZE) { +- DBG_DD(ErrorF("SaveVideoRegister: Out of video register space")); +- } + } + + /* +@@ -224,6 +253,7 @@ + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; + } ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE; + break; + case VIA_KM400: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; +@@ -232,6 +262,7 @@ + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE; + break; + case VIA_K8M800: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; +@@ -240,6 +271,7 @@ + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE; + break; + case VIA_PM800: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; +@@ -248,6 +280,8 @@ + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE; ++ HWDiff->HQVCmeRegs = hqv_cme_regs; + break; + case VIA_VM800: + case VIA_P4M900: +@@ -257,6 +291,8 @@ + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE; ++ HWDiff->HQVCmeRegs = hqv_cme_regs; + break; + case VIA_K8M890: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; +@@ -265,6 +301,8 @@ + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_TRUE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE; ++ HWDiff->HQVCmeRegs = hqv_cme_regs; + break; + case VIA_P4M890: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; +@@ -273,6 +311,8 @@ + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE; ++ HWDiff->HQVCmeRegs = hqv_cme_regs; + break; + case VIA_CX700: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; +@@ -281,8 +321,19 @@ + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE; ++ HWDiff->HQVCmeRegs = hqv_cme_regs; + break; + case VIA_VX800: ++ HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; ++ HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; ++ HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE; ++ HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; ++ HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE; ++ HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_TRUE; ++ HWDiff->HQVCmeRegs = hqv_cme_regs; ++ break; + case VIA_VX855: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; + HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; +@@ -290,6 +341,8 @@ + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE; + HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE; ++ HWDiff->dwNewScaleCtl = VID_HWDIFF_TRUE; ++ HWDiff->HQVCmeRegs = hqv_cme_regs_409; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, +@@ -509,10 +562,12 @@ + unsigned long *pMiniCtl, + unsigned long *pHQVfilterCtl, + unsigned long *pHQVminiCtl, ++ unsigned long *pHQVscaleCtlH, + unsigned long *pHQVzoomflag) + { + unsigned long tmp, sw1, d, falign, mdiv; + Bool zoom_ok = TRUE; ++ VIAHWDiff *hwDiff = &pVia->HWDiff; + + CARD32 HQVfilter[5] = { HQV_H_FILTER_DEFAULT, HQV_H_TAP4_121, + HQV_H_TAP4_121, HQV_H_TAP8_12221, HQV_H_TAP8_12221 +@@ -525,24 +580,57 @@ + if (srcWidth == dstWidth) { /* No zoom */ + *pHQVfilterCtl |= HQV_H_FILTER_DEFAULT; + } else if (srcWidth < dstWidth) { /* Zoom in */ ++ *pZoomCtl &= 0x0000FFFF; ++ tmp = srcWidth * 0x800 / dstWidth; ++ *pZoomCtl |= ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE; ++ *pMiniCtl |= V1_X_INTERPOLY; ++ zoom_ok = !(tmp > 0x7ff); + +- tmp = srcWidth * 0x800 / dstWidth; +- *pZoomCtl = ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE; +- *pMiniCtl |= V1_X_INTERPOLY; +- zoom_ok = !(tmp > 0x7ff); ++ *pHQVzoomflag = 1; ++ *pHQVfilterCtl |= HQV_H_FILTER_DEFAULT; ++ } else { /* srcWidth > dstWidth - Zoom out */ ++ if (hwDiff->dwNewScaleCtl) { ++ if (srcWidth > (dstWidth << 3)) { ++ /*<1/8*/ ++ /*FIXME!*/ ++ if (dstWidth <= 32) { ++ dstWidth = 33; ++ } ++ if (srcWidth > (dstWidth << 5)) { ++ tmp = 1 * 0x1000 / 31; ++ } else { ++ tmp = (dstWidth * 0x1000) / srcWidth; ++ } + +- *pHQVzoomflag = 1; +- *pHQVfilterCtl |= HQV_H_FILTER_DEFAULT; ++ *pHQVscaleCtlH = HQV_H_SCALE_DOWN_UNDER_EIGHTH; ++ } else if (srcWidth == (dstWidth << 3)) { ++ /*1/8*/ ++ tmp = ((dstWidth - 1) * 0x1000) / srcWidth; ++ *pHQVscaleCtlH = HQV_H_SCALE_DOWN_UNDER_EIGHTH; ++ } else if (srcWidth > (dstWidth << 2)) { ++ /*1/4 -1/8 zoom-out*/ ++ tmp = (srcWidth * 0x1000) / dstWidth; ++ *pHQVscaleCtlH = HQV_H_SCALE_DOWN_FOURTH_TO_EIGHTH; ++ } else { ++ /*1-1/4 zoom-out*/ ++ /*setting :src/(destination+0.5)*/ ++ tmp = (srcWidth * 0x2000) / ((dstWidth << 1) + 1); ++ *pHQVscaleCtlH = HQV_H_SCALE_DOWN_FOURTH_TO_1; ++ } + +- } else { /* srcWidth > dstWidth - Zoom out */ ++ /*rounding to nearest interger*/ ++ tmp += (((tmp * 0x1000) & 0xfff) > 1) ? 1 : 0; ++ *pHQVscaleCtlH |= (tmp & 0x7fff) | HQV_H_SCALE_ENABLE; ++ } else { ++ /* HQV rounding patch, instead of: ++ * //tmp = dstWidth*0x0800 / srcWidth; */ ++ tmp = dstWidth * 0x800 * 0x400 / srcWidth; ++ tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0); + +- /* HQV rounding patch, instead of: +- * //tmp = dstWidth*0x0800 / srcWidth; */ +- tmp = dstWidth * 0x800 * 0x400 / srcWidth; +- tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0); ++ *pHQVminiCtl = (tmp & 0x7ff) | HQV_H_MINIFY_ENABLE | HQV_H_MINIFY_DOWN; + +- *pHQVminiCtl = (tmp & 0x7ff) | HQV_H_MINIFY_ENABLE | HQV_H_MINIFY_DOWN; +- ++ *pHQVminiCtl |= HQV_HDEBLOCK_FILTER; ++ } + /* Scale down the picture by a factor mdiv = (1 << d) = {2, 4, 8 or 16} */ + + sw1 = srcWidth; +@@ -561,27 +649,25 @@ + *pMiniCtl |= ((d << 1) - 1) << 24; /* <= {1,3,5,7} << 24 */ + + *pHQVfilterCtl |= HQVfilter[d]; +- /* *pHQVminiCtl = HQVmini[d]; */ +- *pHQVminiCtl |= HQV_HDEBLOCK_FILTER; + +- /* Scale to arbitrary size, on top of previous scaling by (1 << d). */ ++ /* Scale to arbitrary size, on top of previous scaling by (1 << d). */ + +- if (sw1 < dstWidth) { +- /* CLE bug +- *pZoomCtl = sw1 * 0x0800 / dstWidth;*/ +- *pZoomCtl = (sw1 - 2) * 0x0800 / dstWidth; +- *pZoomCtl = ((*pZoomCtl & 0x7ff) << 16) | V1_X_ZOOM_ENABLE; +- } +- } ++ if (sw1 < dstWidth) { ++ /* CLE bug ++ *pZoomCtl = sw1 * 0x0800 / dstWidth;*/ ++ *pZoomCtl = (sw1 - 2) * 0x0800 / dstWidth; ++ *pZoomCtl = ((*pZoomCtl & 0x7ff) << 16) | V1_X_ZOOM_ENABLE; ++ } + +- if (videoFlag & VIDEO_1_INUSE) { +- pVia->swov.overlayRecordV1.dwFetchAlignment = falign; +- pVia->swov.overlayRecordV1.dwminifyH = mdiv; +- } else { +- pVia->swov.overlayRecordV3.dwFetchAlignment = falign; +- pVia->swov.overlayRecordV3.dwminifyH = mdiv; +- } ++ if (videoFlag & VIDEO_1_INUSE) { ++ pVia->swov.overlayRecordV1.dwFetchAlignment = falign; ++ pVia->swov.overlayRecordV1.dwminifyH = mdiv; ++ } else { ++ pVia->swov.overlayRecordV3.dwFetchAlignment = falign; ++ pVia->swov.overlayRecordV3.dwminifyH = mdiv; ++ } + ++ } + return zoom_ok; + } + +@@ -591,10 +677,12 @@ + unsigned long *pZoomCtl, unsigned long *pMiniCtl, + unsigned long *pHQVfilterCtl, + unsigned long *pHQVminiCtl, ++ unsigned long *pHQVscaleCtlV, + unsigned long *pHQVzoomflag) + { + unsigned long tmp, sh1, d; + Bool zoom_ok = TRUE; ++ VIAHWDiff *hwDiff = &pVia->HWDiff; + + CARD32 HQVfilter[5] = { HQV_V_TAP4_121, HQV_V_TAP4_121, HQV_V_TAP4_121, + HQV_V_TAP8_12221, HQV_V_TAP8_12221 }; +@@ -608,48 +696,58 @@ + if (srcHeight == dstHeight) { /* No zoom */ + *pHQVfilterCtl |= HQV_V_TAP4_121; + } else if (srcHeight < dstHeight) { /* Zoom in */ ++ *pZoomCtl &= 0xFFFF0000; ++ tmp = srcHeight * 0x400 / dstHeight - 1; ++ *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE); ++ *pMiniCtl |= (V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY); + +- tmp = srcHeight * 0x0400 / dstHeight; +- *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE); +- *pMiniCtl |= (V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY); +- +- *pHQVzoomflag = 1; +- *pHQVfilterCtl |= HQV_V_TAP4_121; ++ *pHQVzoomflag = 1; ++ *pHQVfilterCtl |= HQV_V_TAP4_121; + } else { /* srcHeight > dstHeight - Zoom out */ ++ if (hwDiff->dwNewScaleCtl) { ++ /*setting :src/(destination+0.5)*/ ++ tmp = srcHeight * 0x2000 / ((dstHeight << 1) + 1); ++ tmp += (((tmp * 0x1000) & 0xfff) > 1) ? 1 : 0; ++ if ((tmp & 0x1ffff) == 0) { ++ tmp = 0x1ffff; ++ } + +- /* HQV rounding patch, instead of: +- * //tmp = dstHeight*0x0800 / srcHeight; */ +- tmp = dstHeight * 0x0800 * 0x400 / srcHeight; +- tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0); +- *pHQVminiCtl |= (((tmp & 0x7ff) << 16) | HQV_V_MINIFY_ENABLE +- | HQV_V_MINIFY_DOWN); ++ *pHQVscaleCtlV = (tmp & 0x1ffff) | HQV_V_SCALE_ENABLE| HQV_V_SCALE_DOWN; ++ } else { ++ /* HQV rounding patch, instead of: ++ * //tmp = dstHeight*0x0800 / srcHeight; */ ++ tmp = dstHeight * 0x0800 * 0x400 / srcHeight; ++ tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0); ++ *pHQVminiCtl |= (((tmp & 0x7ff) << 16) | HQV_V_MINIFY_ENABLE ++ | HQV_V_MINIFY_DOWN); + +- /* Scale down the picture by a factor (1 << d) = {2, 4, 8 or 16} */ ++ /* Scale down the picture by a factor (1 << d) = {2, 4, 8 or 16} */ ++ ++ sh1 = srcHeight; ++ for (d = 1; d < 5; d++) { ++ sh1 >>= 1; ++ if (sh1 <= dstHeight) ++ break; ++ } ++ if (d == 5) { /* Too small. */ ++ d = 4; ++ zoom_ok = FALSE; ++ } + +- sh1 = srcHeight; +- for (d = 1; d < 5; d++) { +- sh1 >>= 1; +- if (sh1 <= dstHeight) +- break; +- } +- if (d == 5) { /* Too small. */ +- d = 4; +- zoom_ok = FALSE; +- } ++ *pMiniCtl |= ((d << 1) - 1) << 16; /* <= {1,3,5,7} << 16 */ + +- *pMiniCtl |= ((d << 1) - 1) << 16; /* <= {1,3,5,7} << 16 */ ++ *pHQVfilterCtl |= HQVfilter[d]; ++ /* *pHQVminiCtl |= HQVmini[d]; */ ++ *pHQVminiCtl |= HQV_VDEBLOCK_FILTER; + +- *pHQVfilterCtl |= HQVfilter[d]; +- /* *pHQVminiCtl |= HQVmini[d]; */ +- *pHQVminiCtl |= HQV_VDEBLOCK_FILTER; ++ /* Scale to arbitrary size, on top of previous scaling by (1 << d). */ + +- /* Scale to arbitrary size, on top of previous scaling by (1 << d). */ +- +- if (sh1 < dstHeight) { +- tmp = sh1 * 0x0400 / dstHeight; +- *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE); +- *pMiniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY; +- } ++ if (sh1 < dstHeight) { ++ tmp = sh1 * 0x0400 / dstHeight; ++ *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE); ++ *pMiniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY; ++ } ++ } + } + + return zoom_ok; +@@ -1488,6 +1586,7 @@ + + if (videoFlag & VIDEO_1_INUSE) { + SaveVideoRegister(pVia, V_COLOR_KEY, keyLow); ++ SaveVideoRegister(pVia, SND_COLOR_KEY, keyLow); + } else { + if (pVia->HWDiff.dwSupportTwoColorKey) /*CLE_C0 */ + SaveVideoRegister(pVia, V3_COLOR_KEY, keyLow); +@@ -1561,8 +1660,9 @@ + srcFetch >>= 3; /* fetch unit is 8 bytes */ + } + +- SaveVideoRegister(pVia, HQV_SRC_FETCH_LINE + proReg, +- ((srcFetch - 1) << 16) | (srcHeight - 1)); ++ if (pVia->ChipId != PCI_CHIP_VT3409) ++ SaveVideoRegister(pVia, HQV_SRC_FETCH_LINE + proReg, ++ ((srcFetch - 1) << 16) | (srcHeight - 1)); + } + + static void +@@ -1713,13 +1813,14 @@ + unsigned long zoomCtl = 0, miniCtl = 0; + unsigned long hqvCtl = 0; + unsigned long hqvFilterCtl = 0, hqvMiniCtl = 0; ++ unsigned long hqvScaleCtlH = 0, hqvScaleCtlV = 0; + unsigned long haveHQVzoomH = 0, haveHQVzoomV = 0; + unsigned long hqvSrcWidth = 0, hqvDstWidth = 0; + unsigned long hqvSrcFetch = 0, hqvOffset = 0; + unsigned long dwOffset = 0, fetch = 0, tmp = 0; + unsigned long proReg = 0; + +- DBG_DD(ErrorF("videoflag=%p\n", videoFlag)); ++ DBG_DD(ErrorF("videoflag=%ld\n", videoFlag)); + + if (pVia->ChipId == PCI_CHIP_VT3259 && !(videoFlag & VIDEO_1_INUSE)) + proReg = PRO_HQV1_OFFSET; +@@ -1762,16 +1863,16 @@ + + /* + * FIXME: +- * Enable video on secondary ++ * Enable video on secondary (change Panel to SecondCRTC?) + */ + if ((pVia->VideoEngine == VIDEO_ENGINE_CME + || pVia->Chipset == VIA_VM800) + && pVia->pBIOSInfo->Panel->IsActive) { + + /* V1_ON_SND_DISPLAY */ +- vidCtl |= 0x80000000; ++ vidCtl |= V1_ON_SND_DISPLAY; + /* SECOND_DISPLAY_COLOR_KEY_ENABLE */ +- compose |= 0x00010000 | 0x1; ++ compose |= SECOND_DISPLAY_COLOR_KEY_ENABLE | 0x1; + } + + viaOverlayGetV1V3Format(pVia, (videoFlag & VIDEO_1_INUSE) ? 1 : 3, +@@ -1925,7 +2026,7 @@ + + if (!viaOverlayHQVCalcZoomWidth(pVia, videoFlag, srcWidth, dstWidth, + &zoomCtl, &miniCtl, &hqvFilterCtl, +- &hqvMiniCtl, &haveHQVzoomH)) { ++ &hqvMiniCtl, &hqvScaleCtlH, &haveHQVzoomH)) { + /* Need to scale (minify) too much - can't handle it. */ + SetFetch(pVia, videoFlag, fetch); + FireVideoCommand(pVia, videoFlag, compose); +@@ -1964,7 +2065,7 @@ + + if (!viaOverlayHQVCalcZoomHeight(pVia, srcHeight, dstHeight, &zoomCtl, + &miniCtl, &hqvFilterCtl, &hqvMiniCtl, +- &haveHQVzoomV)) { ++ &hqvScaleCtlV, &haveHQVzoomV)) { + /* Need to scale (minify) too much - can't handle it. */ + FireVideoCommand(pVia, videoFlag, compose); + FlushVidRegBuffer(pVia); +@@ -2008,8 +2109,13 @@ + hqvFilterCtl &= 0xfffdffff; + SetMiniAndZoom(pVia, videoFlag, 0, 0); + } +- SaveVideoRegister(pVia, HQV_MINIFY_CONTROL + proReg, hqvMiniCtl); +- SaveVideoRegister(pVia, HQV_FILTER_CONTROL + proReg, hqvFilterCtl); ++ if (hwDiff->dwNewScaleCtl) { ++ SaveVideoRegister(pVia, HQV_H_SCALE_CONTROL + proReg, hqvScaleCtlH); ++ SaveVideoRegister(pVia, HQV_V_SCALE_CONTROL + proReg, hqvScaleCtlV); ++ } else { ++ SaveVideoRegister(pVia, HQV_MINIFY_CONTROL + proReg, hqvMiniCtl); ++ } ++ SaveVideoRegister(pVia, HQV_FILTER_CONTROL + proReg, hqvFilterCtl); + } else + SetMiniAndZoom(pVia, videoFlag, miniCtl, zoomCtl); + +@@ -2022,11 +2128,24 @@ + miniCtl, compose); + + if (pVia->VideoEngine == VIDEO_ENGINE_CME) { +- VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL1,0); +- VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL3,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1)); ++ SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL1),0); ++ SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL3),((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1)); + if (pVia->Chipset == VIA_VX800 || pVia->Chipset == VIA_VX855) { +- VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL2,0); +- VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL4,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1)); ++ SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL2),0); ++ SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL4),((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1)); ++ if (pVia->Chipset == VIA_VX855) { ++ SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL1,0); ++ SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL3,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1)); ++ SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL2,0); ++ SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL4,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1)); ++ SaveVideoRegister(pVia, HQV_BACKGROUND_DATA_OFFSET,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1)); ++ SaveVideoRegister(pVia, HQV_EXTENDED_CONTROL,0); ++ /*0x3e0*/ ++ SaveVideoRegister(pVia, HQV_SUBP_HSCALE_CTRL,0); ++ /*0x3e8*/ ++ SaveVideoRegister(pVia, HQV_SUBP_VSCALE_CTRL,0); ++ SaveVideoRegister(pVia, HQV_DEFAULT_VIDEO_COLOR, HQV_FIX_COLOR); ++ } + } + } + +@@ -2062,9 +2181,6 @@ + usleep(1); + } + +- if (pVia->VideoEngine == VIDEO_ENGINE_CME) +- hqvCtl |= HQV_GEN_IRQ; +- + VIDOutD(HQV_CONTROL + proReg, hqvCtl & ~HQV_SW_FLIP); + VIDOutD(HQV_CONTROL + proReg, hqvCtl | HQV_SW_FLIP); + +Index: src/via_driver.h +=================================================================== +--- src/via_driver.h (revision 811) ++++ src/via_driver.h (working copy) +@@ -127,9 +127,10 @@ + CARD8 SR27, SR28, SR29, SR2A,SR2B,SR2C,SR2D,SR2E; + CARD8 SR2F, SR30, SR31, SR32,SR33,SR34,SR40,SR41; + CARD8 SR42, SR43, SR44, SR45,SR46,SR47,SR48,SR49; +- CARD8 SR4A, SR4B, SR4C; ++ CARD8 SR4A, SR4B, SR4C, SR4D; + + /* extended CRTC registers */ ++ CARD8 CR0C, CR0D; + CARD8 CR13, CR30, CR31, CR32, CR33, CR34, CR35, CR36; + CARD8 CR37, CR38, CR39, CR3A, CR40, CR41, CR42, CR43; + CARD8 CR44, CR45, CR46, CR47, CR48, CR49, CR4A; +@@ -142,7 +143,7 @@ + } VIARegRec, *VIARegPtr; + + /* +- * varables that need to be shared among different screens. ++ * variables that need to be shared among different screens. + */ + typedef struct { + Bool b3DRegsInitialized; +@@ -285,6 +286,7 @@ + Bool agpDMA; + Bool nPOT[VIA_NUM_TEXUNITS]; + const unsigned *TwodRegs; ++ const unsigned *HqvCmeRegs; + ExaDriverPtr exaDriverPtr; + ExaOffscreenArea *exa_scratch; + unsigned int exa_scratch_next; +@@ -412,16 +414,18 @@ + void *cursorMap; + CARD32 cursorOffset; + ++ CARD8 I2CDevices; /* Option */ ++ + #ifdef HAVE_DEBUG + Bool disableXvBWCheck; + Bool DumpVGAROM; + Bool PrintVGARegs; + Bool PrintTVRegs; + Bool I2CScan; ++#endif /* HAVE_DEBUG */ + + Bool UseLegacyModeSwitch ; + video_via_regs* VideoRegs ; +-#endif /* HAVE_DEBUG */ + } VIARec, *VIAPtr; + + #define VIAPTR(p) ((VIAPtr)((p)->driverPrivate)) +@@ -433,7 +437,7 @@ + Bool HasSecondary; + Bool BypassSecondary; + /*These two registers are used to make sure the CRTC2 is +- retored before CRTC_EXT, otherwise it could lead to blank screen.*/ ++ restored before CRTC_EXT, otherwise it could lead to blank screen.*/ + Bool IsSecondaryRestored; + Bool RestorePrimary; + +Index: src/via_bios.h +=================================================================== +--- src/via_bios.h (revision 811) ++++ src/via_bios.h (working copy) +@@ -82,6 +82,11 @@ + #define VIA_DEVICE_TV 0x04 + #define VIA_DEVICE_DFP 0x08 + ++#define VIA_I2C_NONE 0x00 ++#define VIA_I2C_BUS1 0x01 ++#define VIA_I2C_BUS2 0x02 ++#define VIA_I2C_BUS3 0x04 ++ + /* System Memory CLK */ + #define VIA_MEM_SDR66 0x00 + #define VIA_MEM_SDR100 0x01 +@@ -92,7 +97,9 @@ + #define VIA_MEM_DDR400 0x06 + #define VIA_MEM_DDR533 0x07 + #define VIA_MEM_DDR667 0x08 +-#define VIA_MEM_END 0x09 ++#define VIA_MEM_DDR800 0x09 ++#define VIA_MEM_DDR1066 0x0A ++#define VIA_MEM_END 0x0B + #define VIA_MEM_NONE 0xFF + + /* Digital Output Bus Width */ +Index: src/via_swov.h +=================================================================== +--- src/via_swov.h (revision 811) ++++ src/via_swov.h (working copy) +@@ -53,7 +53,7 @@ + { + unsigned long dwThreeHQVBuffer; /* Use Three HQV Buffers */ + /* unsigned long dwV3SrcHeightSetting; *//* Set Video Source Width and Height */ +- /* unsigned long dwSupportExtendFIFO; *//* Support Extand FIFO */ ++ /* unsigned long dwSupportExtendFIFO; *//* Support Extend FIFO */ + unsigned long dwHQVFetchByteUnit; /* HQV Fetch Count unit is byte */ + unsigned long dwHQVInitPatch; /* Initialize HQV Engine 2 times */ + /*unsigned long dwSupportV3Gamma; *//* Support V3 Gamma */ +@@ -73,6 +73,8 @@ + /*unsigned long dwV3FIFOPatch; *//* For CLE V3 FIFO Bug (srcWidth <= 8) */ + unsigned long dwSupportTwoColorKey; /* Support two color key */ + /* unsigned long dwCxColorSpace; *//* CLE_Cx ColorSpace */ ++ unsigned dwNewScaleCtl; /* Use new HQV scale engine code */ ++ const unsigned *HQVCmeRegs; /* Which set of CME regs to use for newer chipsets */ + } VIAHWDiff; + + void VIAVidHWDiffInit(ScrnInfoPtr pScrn); +Index: src/via_bandwidth.c +=================================================================== +--- src/via_bandwidth.c (revision 811) ++++ src/via_bandwidth.c (working copy) +@@ -194,6 +194,7 @@ + else + ViaSeqMask(hwp, 0x22, 0x00, 0x1F); /* 128/4 = overflow = 0 */ + break; ++ /* PM800/PM880/CN400 */ + case VIA_PM800: + hwp->writeSeq(hwp, 0x17, 0x5F); /* 95 */ + ViaSeqMask(hwp, 0x16, 0x20, 0xBF); /* 32 */ +@@ -204,9 +205,10 @@ + else + ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 31 */ + break; ++ /* P4M800Pro/VN800/CN700 */ + case VIA_VM800: + hwp->writeSeq(hwp, 0x17, 0x2F); +- ViaSeqMask(hwp, 0x16, 0x14, 0xBF); ++ ViaSeqMask(hwp, 0x16, 0x14, 0xBF); /* 80/4 = 20 = 0x14 */ + ViaSeqMask(hwp, 0x18, 0x08, 0xBF); + + if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) +@@ -215,40 +217,60 @@ + ViaSeqMask(hwp, 0x22, 0x00, 0x1F); + break; + case VIA_K8M890: +- hwp->writeSeq(hwp, 0x16, 0x92); +- hwp->writeSeq(hwp, 0x17, 0xB3); +- hwp->writeSeq(hwp, 0x18, 0x8A); ++ /* depth location: {SR17,0,7} */ ++ hwp->writeSeq(hwp, 0x17, 0xB3); /* 360/2-1 = 179 = 0xB3 */ ++ /* Formula (x & 0x3F) | ((x & 0x40) << 1) */ ++ /* threshold location: {SR16,0,5},{SR16,7,7} */ ++ ViaSeqMask(hwp, 0x16, 0x92, 0xBF); /* 328/4 = 82 = 0x52 */ ++ /* high threshold location: {SR18,0,5},{SR18,7,7} */ ++ ViaSeqMask(hwp, 0x18, 0x8A, 0xBF); /* 296/4 = 74 = 0x4A */ ++ /* display queue expire num location: {SR22,0,4}. */ ++ ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 124/4 = 31 = 0x1F */ + break; + case VIA_P4M900: +- ViaSeqMask(hwp, 0x17, 0x2F, 0xFF); +- ViaSeqMask(hwp, 0x16, 0x13, 0x3F); +- ViaSeqMask(hwp, 0x16, 0x00, 0x80); +- ViaSeqMask(hwp, 0x18, 0x13, 0x3F); +- ViaSeqMask(hwp, 0x18, 0x00, 0x80); ++ /* location: {SR17,0,7} */ ++ hwp->writeSeq(hwp, 0x17, 0x2F); /* 96/2-1 = 47 = 0x2F */ ++ /* location: {SR16,0,5},{SR16,7,7} */ ++ ViaSeqMask(hwp, 0x16, 0x13, 0xBF); /* 76/4 = 19 = 0x13 */ ++ /* location: {SR18,0,5},{SR18,7,7} */ ++ ViaSeqMask(hwp, 0x18, 0x13, 0xBF); /* 76/4 = 19 = 0x13 */ ++ /* location: {SR22,0,4}. */ ++ ViaSeqMask(hwp, 0x22, 0x08, 0x1F); /* 32/4 = 8 = 0x08 */ + break; + case VIA_P4M890: +- hwp->writeSeq(hwp, 0x16, 0x13); +- hwp->writeSeq(hwp, 0x17, 0x2F); +- hwp->writeSeq(hwp, 0x18, 0x53); +- hwp->writeSeq(hwp, 0x22, 0x10); ++ hwp->writeSeq(hwp, 0x17, 0x2F); /* 96/2-1 = 47 = 0x2F */ ++ ViaSeqMask(hwp, 0x16, 0x13, 0xBF); /* 76/4 = 19 = 0x13 */ ++ ViaSeqMask(hwp, 0x18, 0x10, 0xBF); /* 64/4 = 16 = 0x10 */ ++ ViaSeqMask(hwp, 0x22, 0x08, 0x1F); /* 32/4 = 8 = 0x08 */ + break; + case VIA_CX700: +- hwp->writeSeq(hwp, 0x16, 0x26); + hwp->writeSeq(hwp, 0x17, 0x5F); +- hwp->writeSeq(hwp, 0x18, 0x66); +- hwp->writeSeq(hwp, 0x22, 0x1F); ++ ViaSeqMask(hwp, 0x16, 0x20, 0xBF); /* 128/4 = 32 = 0x20 */ ++ ViaSeqMask(hwp, 0x18, 0x20, 0xBF); /* 128/4 = 32 = 0x20 */ ++ ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 124/4 = 31 = 0x1F */ + break; + case VIA_VX800: +- hwp->writeSeq(hwp, 0x16, 0x26); /* 152/4 = 38 */ +- hwp->writeSeq(hwp, 0x17, 0x5F); /* 192/2-1 = 95 */ ++ hwp->writeSeq(hwp, 0x17, 0x5F); /* 192/2-1 = 95 = 0x5F */ ++ hwp->writeSeq(hwp, 0x16, 0x26); /* 152/4 = 38 = 0x26 */ + hwp->writeSeq(hwp, 0x18, 0x26); /* 152/4 = 38 */ + hwp->writeSeq(hwp, 0x22, 0x10); /* 64/4 = 16 */ + break; + case VIA_VX855: +- hwp->writeSeq(hwp, 0x16, 0x50); /* 320/4 = 80 */ +- hwp->writeSeq(hwp, 0x17, 0xC7); /* 400/2-1 = 199 */ +- hwp->writeSeq(hwp, 0x18, 0x50); /* 320/4 = 80 */ +- hwp->writeSeq(hwp, 0x22, 0x28); /* 160/4 = 40 */ ++ hwp->writeSeq(hwp, 0x17, 0xC7); /* 400/2-1 = 199 = 0xC7 */ ++ /* Formula for {SR16,0,5},{SR16,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */ ++ hwp->writeSeq(hwp, 0x16, 0x90); /* 320/4 = 80 = 0x50 */ ++ /* Formula for {SR18,0,5},{SR18,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */ ++ hwp->writeSeq(hwp, 0x18, 0x90); /* 320/4 = 80 = 0x50 */ ++ hwp->writeSeq(hwp, 0x22, 0x28); /* 160/4 = 40 = 0x28 */ ++ break; ++ case VIA_VX900: ++ hwp->writeSeq(hwp, 0x17, 0xC7); /* 400/2-1 = 199 = 0xC7 */ ++ /* Formula for {SR16,0,5},{SR16,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */ ++ hwp->writeSeq(hwp, 0x16, 0x90); /* 320/4 = 80 = 0x50 */ ++ /* Formula for {SR18,0,5},{SR18,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */ ++ hwp->writeSeq(hwp, 0x18, 0x90); /* 320/4 = 80 = 0x50 */ ++ hwp->writeSeq(hwp, 0x22, 0x28); /* 160/4 = 40 = 0x28 */ ++ break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetPrimaryFIFO: " + "Chipset %d not implemented\n", pVia->Chipset); +@@ -371,7 +393,38 @@ + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); + break; + case VIA_P4M890: ++ /* depth location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ ++ ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); /* 96/8-1 = 11 = 0x0B */ ++ ViaCrtcMask(hwp, 0x94, 0x00, 0x80); ++ ViaCrtcMask(hwp, 0x95, 0x00, 0x80); ++ ++ /* location: {CR68,0,3},{CR95,4,6} */ ++ ViaCrtcMask(hwp, 0x68, 0x03, 0x0F); /* 76/4 = 19 = 0x13 */ ++ ViaCrtcMask(hwp, 0x95, 0x10, 0x70); ++ ++ /* location: {CR92,0,3},{CR95,0,2} */ ++ ViaCrtcMask(hwp, 0x92, 0x00, 0x0F); /* 64/4 = 16 = 0x10 */ ++ ViaCrtcMask(hwp, 0x95, 0x01, 0x07); ++ ++ /* location: {CR94,0,6} */ ++ ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); /* 32/4 = 8 = 0x08 */ ++ break; + case VIA_K8M890: ++ /* Display Queue Depth, location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ ++ ViaCrtcMask(hwp, 0x68, 0xC0, 0xF0); /* 360/8-1 = 44 = 0x2C; 0x2C << 4 = 0xC0 */ ++ ViaCrtcMask(hwp, 0x94, 0x00, 0x80); /* 0x2C << 3 = 0x00 */ ++ ViaCrtcMask(hwp, 0x95, 0x80, 0x80); /* 0x2C << 2 = 0x80 */ ++ ++ /* Display Queue Read Threshold 1, location: {CR68,0,3},{CR95,4,6} */ ++ ViaCrtcMask(hwp, 0x68, 0x02, 0x0F); /* 328/4 = 82 = 0x52 */ ++ ViaCrtcMask(hwp, 0x95, 0x50, 0x70); ++ ++ /* location: {CR92,0,3},{CR95,0,2} */ ++ ViaCrtcMask(hwp, 0x92, 0x0A, 0x0F); /* 296/4 = 74 = 0x4A */ ++ ViaCrtcMask(hwp, 0x95, 0x04, 0x07); /* 0x4A >> 4 = 0x04 */ ++ ++ /* Display Expire Number Bits, location: {CR94,0,6} */ ++ ViaCrtcMask(hwp, 0x94, 0x1F, 0x7F); /* 124/4 = 31 = 0x1F */ + break; + case VIA_P4M900: + ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); +@@ -402,8 +455,8 @@ + break; + case VIA_VX800: + /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 96/8-1 = 0x0B */ +- ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0); +- ViaCrtcMask(hwp, 0x94, 0x00, 0x80); ++ ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); /* ((0x0B & 0x0F) << 4)) = 0xB0 */ ++ ViaCrtcMask(hwp, 0x94, 0x00, 0x80); /* ((0x0B & 0x10) << 3)) = 0x00 */ + ViaCrtcMask(hwp, 0x95, 0x00, 0x80); + /* {CR68,0,3},{CR95,4,6} : 64/4 = 0x10 */ + ViaCrtcMask(hwp, 0x68, 0x04, 0x0F); +@@ -418,7 +471,39 @@ + ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); + break; + case VIA_VX855: ++ /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 200/8-1 = 24 = 0x18 */ ++ ViaCrtcMask(hwp, 0x68, 0x80, 0xF0); /* ((0x18 & 0x0F) << 4)) = 0x80 */ ++ ViaCrtcMask(hwp, 0x94, 0x80, 0x80); /* ((0x18 & 0x10) << 3)) = 0x80 */ ++ ViaCrtcMask(hwp, 0x95, 0x00, 0x80); /* ((0x18 & 0x20) << 2)) = 0x00 */ ++ /* {CR68,0,3},{CR95,4,6} : 160/4 = 0x28 */ ++ ViaCrtcMask(hwp, 0x68, 0x08, 0x0F); /* (0x28 & 0x0F) = 0x08 */ ++ ViaCrtcMask(hwp, 0x95, 0x20, 0x70); /* (0x28 & 0x70) = 0x20 */ ++ /* {CR92,0,3},{CR95,0,2} : 160/4 = 0x28 */ ++ ViaCrtcMask(hwp, 0x92, 0x08, 0x08); /* (0x28 & 0x0F) = 0x08 */ ++ ViaCrtcMask(hwp, 0x95, 0x02, 0x07); /* ((0x28 & 0x70) >> 4)) = 0x02 */ ++ /* {CR94,0,6} : 320/4 = 0x50 */ ++ if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) ++ ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); ++ else ++ ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); + break; ++ case VIA_VX900: ++ /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 192/8-1 = 23 = 0x17 */ ++ ViaCrtcMask(hwp, 0x68, 0x70, 0xF0); /* ((0x17 & 0x0F) << 4)) = 0x70 */ ++ ViaCrtcMask(hwp, 0x94, 0x80, 0x80); /* ((0x17 & 0x10) << 3)) = 0x80 */ ++ ViaCrtcMask(hwp, 0x95, 0x00, 0x80); /* ((0x17 & 0x20) << 2)) = 0x00 */ ++ /* {CR68,0,3},{CR95,4,6} : 160/4 = 0x28 */ ++ ViaCrtcMask(hwp, 0x68, 0x08, 0x0F); /* (0x28 & 0x0F) = 0x08 */ ++ ViaCrtcMask(hwp, 0x95, 0x20, 0x70); /* (0x28 & 0x70) = 0x20 */ ++ /* {CR92,0,3},{CR95,0,2} : 160/4 = 0x28 */ ++ ViaCrtcMask(hwp, 0x92, 0x08, 0x08); /* (0x28 & 0x0F) = 0x08 */ ++ ViaCrtcMask(hwp, 0x95, 0x02, 0x07); /* ((0x28 & 0x70) >> 4)) = 0x2 */ ++ /* {CR94,0,6} : 320/4 = 0x50 */ ++ if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) ++ ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); ++ else ++ ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); ++ break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetSecondaryFIFO: " + "Chipset %d not implemented\n", pVia->Chipset); +Index: src/via_accel.c +=================================================================== +--- src/via_accel.c (revision 811) ++++ src/via_accel.c (working copy) +@@ -196,6 +196,7 @@ + switch (pVia->Chipset) { + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY_H5 | VIA_2D_ENG_BUSY_H5)) + && (loop++ < MAXLOOP)) ; +@@ -287,7 +288,7 @@ + + buf->pScrn = pScrn; + buf->bufSize = ((size == 0) ? VIA_DMASIZE : size) >> 2; +- buf->buf = (CARD32 *) xcalloc(buf->bufSize, sizeof(CARD32)); ++ buf->buf = (CARD32 *) calloc(buf->bufSize, sizeof(CARD32)); + if (!buf->buf) + return BadAlloc; + buf->waitFlags = 0; +@@ -312,7 +313,7 @@ + viaTearDownCBuffer(ViaCommandBuffer * buf) + { + if (buf && buf->buf) +- xfree(buf->buf); ++ free(buf->buf); + buf->buf = NULL; + } + +@@ -417,6 +418,9 @@ + switch (pVia->Chipset) { + case VIA_K8M890: + case VIA_P4M900: ++ case VIA_VX800: ++ case VIA_VX855: ++ case VIA_VX900: + VIASETREG(0x41c, 0x00100000); + VIASETREG(0x420, 0x74301000); + break; +@@ -472,16 +476,25 @@ + VIASETREG(i, 0x0); + } + +- if (pVia->Chipset == VIA_VX800 || pVia->Chipset == VIA_VX855) { +- for (i = 0x44; i < 0x5c; i += 4) { ++ if (pVia->Chipset == VIA_VX800 || ++ pVia->Chipset == VIA_VX855 || ++ pVia->Chipset == VIA_VX900) { ++ for (i = 0x44; i <= 0x5c; i += 4) { + VIASETREG(i, 0x0); + } + } + ++ if (pVia->Chipset == VIA_VX900) ++ { ++ /*410 redefine 0x30 34 38*/ ++ VIASETREG(0x60, 0x0); /*already useable here*/ ++ } ++ + /* Make the VIA_REG() macro magic work */ + switch (pVia->Chipset) { + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + pVia->TwodRegs = via_2d_regs_m1; + break; + default: +@@ -492,6 +505,9 @@ + switch (pVia->Chipset) { + case VIA_K8M890: + case VIA_P4M900: ++ case VIA_VX800: ++ case VIA_VX855: ++ case VIA_VX900: + viaInitPCIe(pVia); + break; + default: +@@ -503,6 +519,9 @@ + switch (pVia->Chipset) { + case VIA_K8M890: + case VIA_P4M900: ++ case VIA_VX800: ++ case VIA_VX855: ++ case VIA_VX900: + viaEnablePCIeVQ(pVia); + break; + default: +@@ -530,6 +549,7 @@ + switch (pVia->Chipset) { + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY_H5 | VIA_2D_ENG_BUSY_H5 | VIA_3D_ENG_BUSY_H5)) + && (loop++ < MAXLOOP)) ; +@@ -582,7 +602,7 @@ + + /* + * This is a small helper to wrap around a PITCH register write +- * to deal with the sublte differences of M1 and old 2D engine ++ * to deal with the subtle differences of M1 and old 2D engine + */ + static void + viaPitchHelper(VIAPtr pVia, unsigned dstPitch, unsigned srcPitch) +@@ -590,7 +610,9 @@ + unsigned val = (dstPitch >> 3) << 16 | (srcPitch >> 3); + RING_VARS; + +- if (pVia->Chipset != VIA_VX800 && pVia->Chipset != VIA_VX855) { ++ if (pVia->Chipset != VIA_VX800 && ++ pVia->Chipset != VIA_VX855 && ++ pVia->Chipset != VIA_VX900) { + val |= VIA_PITCH_ENABLE; + } + OUT_RING_H1(VIA_REG(pVia, PITCH), val); +@@ -759,6 +781,7 @@ + tdc->cmd = cmd; + viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); ++ ADVANCE_RING; + } + + static void +@@ -796,6 +819,7 @@ + tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + tdc->fgColor = color; + viaAccelTransparentHelper(pVia, 0x00, 0x00, FALSE); ++ ADVANCE_RING; + } + + static void +@@ -852,6 +876,7 @@ + tdc->pattern0 = pattern0; + tdc->pattern1 = pattern1; + viaAccelTransparentHelper(pVia, 0x00, 0x00, FALSE); ++ ADVANCE_RING; + } + + static void +@@ -901,6 +926,7 @@ + tdc->patternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl); + viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); ++ ADVANCE_RING; + } + + static void +@@ -962,9 +988,9 @@ + tdc->fgColor = fg; + tdc->bgColor = bg; + ++ viaAccelTransparentHelper(pVia, 0x0, 0x0, FALSE); ++ + ADVANCE_RING; +- +- viaAccelTransparentHelper(pVia, 0x0, 0x0, FALSE); + } + + static void +@@ -991,7 +1017,7 @@ + pScrn->fbOffset + sub * pVia->Bpl, tdc->mode, + pVia->Bpl, pVia->Bpl, tdc->cmd); + +- viaFlushPCI(cb); ++ ADVANCE_RING; + viaDisableClipping(pScrn); + } + +@@ -1005,9 +1031,9 @@ + RING_VARS; + + tdc->cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIAACCELCOPYROP(rop); +- ADVANCE_RING; + viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color, FALSE); ++ ADVANCE_RING; + } + + static void +@@ -1030,7 +1056,7 @@ + pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, + pVia->Bpl, pVia->Bpl, tdc->cmd); + +- viaFlushPCI(cb); ++ ADVANCE_RING; + viaDisableClipping(pScrn); + } + +@@ -1052,6 +1078,7 @@ + OUT_RING_H1(VIA_REG(pVia, GEMODE), tdc->mode); + OUT_RING_H1(VIA_REG(pVia, MONOPAT0), 0xFF); + OUT_RING_H1(VIA_REG(pVia, MONOPATFGC), tdc->fgColor); ++ ADVANCE_RING; + } + + static void +@@ -1189,6 +1216,7 @@ + OUT_RING_H1(VIA_REG(pVia, MONOPATFGC), tdc->fgColor); + OUT_RING_H1(VIA_REG(pVia, MONOPATBGC), tdc->bgColor); + OUT_RING_H1(VIA_REG(pVia, MONOPAT0), tdc->pattern0); ++ ADVANCE_RING; + } + + static void +@@ -1210,7 +1238,8 @@ + + /* General acceleration flags. */ + xaaptr->Flags = (PIXMAP_CACHE | +- OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER | ++ OFFSCREEN_PIXMAPS | ++ LINEAR_FRAMEBUFFER | + MICROSOFT_ZERO_LINE_BIAS | 0); + + if (pScrn->bitsPerPixel == 8) +@@ -1218,24 +1247,31 @@ + + xaaptr->SetClippingRectangle = viaSetClippingRectangle; + xaaptr->DisableClipping = viaDisableClipping; +- xaaptr->ClippingFlags = (HARDWARE_CLIP_SOLID_FILL | +- HARDWARE_CLIP_SOLID_LINE | +- HARDWARE_CLIP_DASHED_LINE | +- HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | ++ xaaptr->ClippingFlags = (HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | + HARDWARE_CLIP_MONO_8x8_FILL | + HARDWARE_CLIP_COLOR_8x8_FILL | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | 0); + ++ if (pVia->Chipset != VIA_VX800 && ++ pVia->Chipset != VIA_VX855 && ++ pVia->Chipset != VIA_VX900) ++ xaaptr->ClippingFlags |= (HARDWARE_CLIP_SOLID_FILL | ++ HARDWARE_CLIP_SOLID_LINE | ++ HARDWARE_CLIP_DASHED_LINE); ++ + xaaptr->Sync = viaAccelSync; + ++ /* ScreenToScreen copies */ + xaaptr->SetupForScreenToScreenCopy = viaSetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = viaSubsequentScreenToScreenCopy; + xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + ++ /* Solid filled rectangles */ + xaaptr->SetupForSolidFill = viaSetupForSolidFill; + xaaptr->SubsequentSolidFillRect = viaSubsequentSolidFillRect; + xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + ++ /* Mono 8x8 pattern fills */ + xaaptr->SetupForMono8x8PatternFill = viaSetupForMono8x8PatternFill; + xaaptr->SubsequentMono8x8PatternFillRect = + viaSubsequentMono8x8PatternFillRect; +@@ -1244,6 +1280,7 @@ + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST | 0); + ++ /* Color 8x8 pattern fills */ + xaaptr->SetupForColor8x8PatternFill = viaSetupForColor8x8PatternFill; + xaaptr->SubsequentColor8x8PatternFillRect = + viaSubsequentColor8x8PatternFillRect; +@@ -1252,12 +1289,14 @@ + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 0); + ++ /* Solid lines */ + xaaptr->SetupForSolidLine = viaSetupForSolidLine; + xaaptr->SubsequentSolidTwoPointLine = viaSubsequentSolidTwoPointLine; + xaaptr->SubsequentSolidHorVertLine = viaSubsequentSolidHorVertLine; + xaaptr->SolidBresenhamLineErrorTermBits = 14; + xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + ++ /* Dashed line */ + xaaptr->SetupForDashedLine = viaSetupForDashedLine; + xaaptr->SubsequentDashedTwoPointLine = viaSubsequentDashedTwoPointLine; + xaaptr->DashPatternMaxLength = 8; +@@ -1266,49 +1305,50 @@ + LINE_PATTERN_POWER_OF_2_ONLY | + LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | 0); + ++ /* CPU to Screen color expansion */ + xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | +- CPU_TRANSFER_PAD_DWORD | +- SCANLINE_PAD_DWORD | +- BIT_ORDER_IN_BYTE_MSBFIRST | +- LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0; ++ CPU_TRANSFER_PAD_DWORD | ++ SCANLINE_PAD_DWORD | ++ BIT_ORDER_IN_BYTE_MSBFIRST | ++ LEFT_EDGE_CLIPPING | ++ ROP_NEEDS_SOURCE | 0; + + xaaptr->SetupForScanlineCPUToScreenColorExpandFill = + viaSetupForCPUToScreenColorExpandFill; + xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = + viaSubsequentScanlineCPUToScreenColorExpandFill; + xaaptr->ColorExpandBase = pVia->BltBase; +- xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE; ++ if (pVia->Chipset == VIA_VX800 || ++ pVia->Chipset == VIA_VX855 || ++ pVia->Chipset == VIA_VX900) ++ xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE; ++ else ++ xaaptr->ColorExpandRange = (64 * 1024); + ++ /* ImageWrite */ + xaaptr->ImageWriteFlags = (NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | +- LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0); +- // SYNC_AFTER_IMAGE_WRITE | 0); ++ LEFT_EDGE_CLIPPING | ++ ROP_NEEDS_SOURCE | ++ NO_GXCOPY | 0); + + /* + * Most Unichromes are much faster using processor-to-framebuffer writes + * than when using the 2D engine for this. +- * test with x11perf -shmput500! ++ * test with "x11perf -shmput500" ++ * Example: K8M890 chipset; with GPU=86.3/sec; without GPU=132.0/sec ++ * TODO Check speed for other chipsets + */ + +- switch (pVia->Chipset) { +- case VIA_K8M800: +- case VIA_K8M890: +- case VIA_P4M900: +- case VIA_VX800: +- case VIA_VX855: +- break; +- default: +- xaaptr->ImageWriteFlags |= NO_GXCOPY; +- break; +- } +- + xaaptr->SetupForImageWrite = viaSetupForImageWrite; + xaaptr->SubsequentImageWriteRect = viaSubsequentImageWriteRect; + xaaptr->ImageWriteBase = pVia->BltBase; + +- if (pVia->Chipset == VIA_VX800 || pVia->Chipset == VIA_VX855) ++ if (pVia->Chipset == VIA_VX800 || ++ pVia->Chipset == VIA_VX855 || ++ pVia->Chipset == VIA_VX900) + xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE; + else + xaaptr->ImageWriteRange = (64 * 1024); +@@ -2344,7 +2384,7 @@ + } + + if (!exaDriverInit(pScreen, pExa)) { +- xfree(pExa); ++ free(pExa); + return NULL; + } + +@@ -2354,7 +2394,7 @@ + + + /* +- * Acceleration initializatuon function. Sets up offscreen memory disposition, ++ * Acceleration initialization function. Sets up offscreen memory disposition, + * and initializes engines and acceleration method. + */ + Bool +@@ -2542,7 +2582,7 @@ + } + } + if (pVia->dBounce) +- xfree(pVia->dBounce); ++ free(pVia->dBounce); + #endif /* XF86DRI */ + if (pVia->scratchAddr) { + exaOffscreenFree(pScreen, pVia->scratchFBBuffer); +@@ -2551,7 +2591,7 @@ + if (pVia->exaDriverPtr) { + exaDriverFini(pScreen); + } +- xfree(pVia->exaDriverPtr); ++ free(pVia->exaDriverPtr); + pVia->exaDriverPtr = NULL; + return; + } +@@ -2577,7 +2617,7 @@ + + if (pVia->directRenderingEnabled && pVia->useEXA) { + +- pVia->dBounce = xcalloc(VIA_DMA_DL_SIZE * 2, 1); ++ pVia->dBounce = calloc(VIA_DMA_DL_SIZE * 2, 1); + + if (!pVia->IsPCI) { + +Index: src/via_vt162x.c +=================================================================== +--- src/via_vt162x.c (revision 811) ++++ src/via_vt162x.c (working copy) +@@ -41,30 +41,42 @@ + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + vgaHWPtr hwp = VGAHWPTR(pScrn); + +- /* External TV: */ +- switch(pVia->Chipset) { +- case VIA_CX700: +- case VIA_VX800: +- if (pBIOSInfo->FirstCRTC->IsActive) { +- if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1) +- ViaCrtcMask(hwp, 0x6C, 0xB0, 0xF0); +- else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0) +- ViaCrtcMask(hwp, 0x6C, 0x90, 0xF0); +- } else { +- /* IGA2 */ +- if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1) +- ViaCrtcMask(hwp, 0x6C, 0x0B, 0x0F); +- else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0) +- ViaCrtcMask(hwp, 0x6C, 0x09, 0x0F); ++ switch(pBIOSInfo->TVEncoder) { ++ case VIA_VT1625: ++ /* External TV: */ ++ switch(pVia->Chipset) { ++ case VIA_CX700: ++ case VIA_VX800: ++ case VIA_VX855: ++ if (pBIOSInfo->FirstCRTC->IsActive) { ++ if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1) ++ ViaCrtcMask(hwp, 0x6C, 0xB0, 0xF0); ++ else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0) ++ ViaCrtcMask(hwp, 0x6C, 0x90, 0xF0); ++ } else { ++ /* IGA2 */ ++ if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1) ++ ViaCrtcMask(hwp, 0x6C, 0x0B, 0x0F); ++ else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0) ++ ViaCrtcMask(hwp, 0x6C, 0x09, 0x0F); ++ } ++ break; ++ default: ++ if (pBIOSInfo->FirstCRTC->IsActive) ++ ViaCrtcMask(hwp, 0x6C, 0x21, 0x21); ++ else ++ ViaCrtcMask(hwp, 0x6C, 0xA1, 0xA1); ++ break; + } + break; + default: + if (pBIOSInfo->FirstCRTC->IsActive) +- ViaCrtcMask(hwp, 0x6C, 0x21, 0x21); ++ ViaCrtcMask(hwp, 0x6C, 0x50, 0xF0); + else +- ViaCrtcMask(hwp, 0x6C, 0xA1, 0xA1); ++ ViaCrtcMask(hwp, 0x6C, 0x05, 0x0F); + break; + } ++ + } + + static void +Index: src/via_vbe.c +=================================================================== +--- src/via_vbe.c (revision 811) ++++ src/via_vbe.c (working copy) +@@ -230,7 +230,7 @@ + /* Some cards do not like setting the clock. */ + xf86ErrorF("...but worked OK without customized " + "refresh and dotclock.\n"); +- xfree(data->block); ++ free(data->block); + data->block = NULL; + data->mode &= ~(1 << 11); + } else { +@@ -322,7 +322,7 @@ + && (function == MODE_SAVE)) { + /* Do not rely on the memory not being touched. */ + if (pVia->vbeMode.pstate == NULL) +- pVia->vbeMode.pstate = xalloc(pVia->vbeMode.stateSize); ++ pVia->vbeMode.pstate = malloc(pVia->vbeMode.stateSize); + memcpy(pVia->vbeMode.pstate, pVia->vbeMode.state, + pVia->vbeMode.stateSize); + } +Index: src/via_xvmc.c +=================================================================== +--- src/via_xvmc.c (revision 811) ++++ src/via_xvmc.c (working copy) +@@ -151,7 +151,7 @@ + for (i = 0; i < VIA_XVMC_MAX_CONTEXTS; ++i) { + vXvMC->contexts[i] = 0; + if (vXvMC->cPrivs[i]) { +- xfree(vXvMC->cPrivs[i]); ++ free(vXvMC->cPrivs[i]); + vXvMC->cPrivs[i] = 0; + } + } +@@ -159,7 +159,7 @@ + for (i = 0; i < VIA_XVMC_MAX_SURFACES; ++i) { + vXvMC->surfaces[i] = 0; + if (vXvMC->sPrivs[i]) { +- xfree(vXvMC->sPrivs[i]); ++ free(vXvMC->sPrivs[i]); + vXvMC->sPrivs[i] = 0; + } + } +@@ -270,7 +270,7 @@ + /* + * Filling in the device dependent adaptor record. + * This is named "VIA Video Overlay" because this code falls under the +- * XV extenstion, the name must match or it won't be used. ++ * XV extension, the name must match or it won't be used. + * + * For surface and subpicture, see above. + * The function pointers point to functions below. +@@ -325,10 +325,11 @@ + + if ((pVia->Chipset == VIA_KM400) || + (pVia->Chipset == VIA_CX700) || ++ (pVia->Chipset == VIA_K8M890) || ++ (pVia->Chipset == VIA_P4M900) || + (pVia->Chipset == VIA_VX800) || + (pVia->Chipset == VIA_VX855) || +- (pVia->Chipset == VIA_K8M890) || +- (pVia->Chipset == VIA_P4M900)) { ++ (pVia->Chipset == VIA_VX900)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[XvMC] XvMC is not supported on this chipset.\n"); + return; +@@ -424,7 +425,7 @@ + viaPortPrivPtr pPriv = XvAdaptors[i]->pPortPrivates[j].ptr; + + if (pPriv->xvmc_priv) +- xfree(pPriv->xvmc_priv); ++ free(pPriv->xvmc_priv); + } + } + pVia->XvMCEnabled = 0; +@@ -460,7 +461,7 @@ + return BadAlloc; + } + +- *priv = xcalloc(1, sizeof(ViaXvMCCreateContextRec)); ++ *priv = calloc(1, sizeof(ViaXvMCCreateContextRec)); + contextRec = (ViaXvMCCreateContextRec *) * priv; + + if (!*priv) { +@@ -475,12 +476,12 @@ + break; + } + +- cPriv = (ViaXvMCContextPriv *) xcalloc(1, sizeof(ViaXvMCContextPriv)); ++ cPriv = (ViaXvMCContextPriv *) calloc(1, sizeof(ViaXvMCContextPriv)); + + if (!cPriv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateContext: Unable to allocate memory!\n"); +- xfree(*priv); ++ free(*priv); + *num_priv = 0; + return BadAlloc; + } +@@ -532,7 +533,7 @@ + return BadAlloc; + } + +- sPriv = (ViaXvMCSurfacePriv *) xcalloc(1, sizeof(ViaXvMCSurfacePriv)); ++ sPriv = (ViaXvMCSurfacePriv *) calloc(1, sizeof(ViaXvMCSurfacePriv)); + + if (!sPriv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, +@@ -566,13 +567,13 @@ + #endif + *num_priv = numBuffers + 2; + +- *priv = (INT32 *) xcalloc(*num_priv, sizeof(INT32)); ++ *priv = (INT32 *) calloc(*num_priv, sizeof(INT32)); + + if (!*priv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] ViaXvMCCreateSurface: Unable to allocate memory!\n"); + *num_priv = 0; +- xfree(sPriv); ++ free(sPriv); + return BadAlloc; + } + +@@ -588,8 +589,8 @@ + sPriv->memory_ref.pool = 0; + if (VIAAllocLinear(&(sPriv->memory_ref), pScrn, + numBuffers * bufSize + 32)) { +- xfree(*priv); +- xfree(sPriv); ++ free(*priv); ++ free(sPriv); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSurface: " + "Unable to allocate frambuffer memory!\n"); + return BadAlloc; +@@ -631,7 +632,7 @@ + return BadAlloc; + } + +- sPriv = (ViaXvMCSurfacePriv *) xcalloc(1, sizeof(ViaXvMCSurfacePriv)); ++ sPriv = (ViaXvMCSurfacePriv *) calloc(1, sizeof(ViaXvMCSurfacePriv)); + + if (!sPriv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSubpicture:" +@@ -640,13 +641,13 @@ + return BadAlloc; + } + +- *priv = (INT32 *) xcalloc(3, sizeof(INT32)); ++ *priv = (INT32 *) calloc(3, sizeof(INT32)); + + if (!*priv) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSubpicture:" + " Unable to allocate memory!\n"); + *num_priv = 0; +- xfree(sPriv); ++ free(sPriv); + return BadAlloc; + } + +@@ -663,8 +664,8 @@ + bufSize = size_xx44(ctx->width, ctx->height); + sPriv->memory_ref.pool = 0; + if (VIAAllocLinear(&(sPriv->memory_ref), pScrn, 1 * bufSize + 32)) { +- xfree(*priv); +- xfree(sPriv); ++ free(*priv); ++ free(sPriv); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSubpicture:" + " Unable to allocate framebuffer memory!\n"); + return BadAlloc; +@@ -701,7 +702,7 @@ + vx->ctxDisplaying = 0; + } + +- xfree(vXvMC->cPrivs[i]); ++ free(vXvMC->cPrivs[i]); + vXvMC->cPrivs[i] = 0; + vXvMC->nContexts--; + vXvMC->contexts[i] = 0; +@@ -736,7 +737,7 @@ + } + + VIAFreeLinear(&(vXvMC->sPrivs[i]->memory_ref)); +- xfree(vXvMC->sPrivs[i]); ++ free(vXvMC->sPrivs[i]); + vXvMC->nSurfaces--; + vXvMC->sPrivs[i] = 0; + vXvMC->surfaces[i] = 0; +@@ -778,7 +779,7 @@ + } + + VIAFreeLinear(&(vXvMC->sPrivs[i]->memory_ref)); +- xfree(vXvMC->sPrivs[i]); ++ free(vXvMC->sPrivs[i]); + vXvMC->nSurfaces--; + vXvMC->sPrivs[i] = 0; + vXvMC->surfaces[i] = 0; +@@ -828,7 +829,7 @@ + for (j = 0; j < XvAdapt->nPorts; ++j) { + pPriv = (viaPortPrivPtr) XvAdapt->pPortPrivates[j].ptr; + +- if (NULL == (pPriv->xvmc_priv = xcalloc(1, sizeof(ViaXvMCXVPriv)))) ++ if (NULL == (pPriv->xvmc_priv = calloc(1, sizeof(ViaXvMCXVPriv)))) + return BadAlloc; + + for (i = 0; i < VIA_NUM_XVMC_ATTRIBUTES; ++i) { +Index: src/via_cursor.c +=================================================================== +--- src/via_cursor.c (revision 811) ++++ src/via_cursor.c (working copy) +@@ -98,6 +98,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + pVia->CursorRegControl = VIA_REG_HI_CONTROL0; + pVia->CursorRegBase = VIA_REG_HI_BASE0; +@@ -145,9 +146,12 @@ + infoPtr->ShowCursor = viaShowCursor; + infoPtr->UseHWCursor = viaUseHWCursor; + ++ /* ARGB Cursor init */ + infoPtr->UseHWCursorARGB = viaUseHWCursorARGB; +- if (pVia->CursorARGBSupported) ++ if (pVia->CursorARGBSupported) { ++ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "HWCursor ARGB enabled\n")); + infoPtr->LoadCursorARGB = viaLoadCursorARGB; ++ } + + /* Set cursor location in frame buffer. */ + VIASETREG(VIA_REG_CURSOR_MODE, pVia->cursorOffset); +@@ -166,6 +170,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + VIASETREG(VIA_REG_PRIM_HI_INVTCOLOR, 0x00FFFFFF); + VIASETREG(VIA_REG_V327_HI_INVTCOLOR, 0x00FFFFFF); +@@ -225,6 +230,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + pVia->CursorPrimHiInvtColor = VIAGETREG(VIA_REG_PRIM_HI_INVTCOLOR); + pVia->CursorV327HiInvtColor = VIAGETREG(VIA_REG_V327_HI_INVTCOLOR); +@@ -265,6 +271,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + VIASETREG(VIA_REG_PRIM_HI_INVTCOLOR, pVia->CursorPrimHiInvtColor); + VIASETREG(VIA_REG_V327_HI_INVTCOLOR, pVia->CursorV327HiInvtColor); +@@ -284,7 +291,7 @@ + } + + /* +- * ARGB Cursor ++ * display the current cursor + */ + + void +@@ -298,6 +305,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + VIASETREG(VIA_REG_HI_CONTROL0, 0x36000005); + } +@@ -319,13 +327,19 @@ + */ + + /* Duoview */ +- if (pVia->CursorPipe) ++ if (pVia->CursorPipe) { ++ /* Mono Cursor Display Path [bit31]: Secondary */ ++ /* FIXME For CLE266 and KM400 try to enable 32x32 cursor size [bit1] */ + VIASETREG(VIA_REG_ALPHA_CONTROL, 0xF6000005); +- else ++ } else { ++ /* Mono Cursor Display Path [bit31]: Primary */ + VIASETREG(VIA_REG_ALPHA_CONTROL, 0x76000005); ++ } + } + } + ++ ++/* hide the current cursor */ + void + viaHideCursor(ScrnInfoPtr pScrn) + { +@@ -338,6 +352,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + temp = VIAGETREG(VIA_REG_HI_CONTROL0); + VIASETREG(VIA_REG_HI_CONTROL0, temp & 0xFFFFFFFA); +@@ -350,10 +365,16 @@ + + default: + temp = VIAGETREG(VIA_REG_ALPHA_CONTROL); ++ /* Hardware cursor disable [bit0] */ + VIASETREG(VIA_REG_ALPHA_CONTROL, temp & 0xFFFFFFFA); + } + } + ++/* ++ Set the cursor position to (x,y). X and/or y may be negative ++ indicating that the cursor image is partially offscreen on ++ the left and/or top edges of the screen. ++*/ + static void + viaSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) + { +@@ -380,6 +401,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + VIASETREG(VIA_REG_HI_POS0, ((x << 16) | (y & 0x07ff))); + VIASETREG(VIA_REG_HI_OFFSET0, ((xoff << 16) | (yoff & 0x07ff))); +@@ -409,6 +431,15 @@ + && pCurs->bits->height <= pVia->CursorMaxHeight); + } + ++/* ++ If the driver is unable to use a hardware cursor for reasons ++ other than the cursor being larger than the maximum specified ++ in the MaxWidth or MaxHeight field below, it can supply the ++ UseHWCursor function. If UseHWCursor is provided by the driver, ++ it will be called whenever the cursor shape changes or the video ++ mode changes. This is useful for when the hardware cursor cannot ++ be used in interlaced or doublescan modes. ++*/ + static Bool + viaUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) + { +@@ -423,8 +454,11 @@ + && pCurs->bits->height <= pVia->CursorMaxHeight); + } + ++/* ++ Load Mono Cursor Image ++*/ + static void +-viaLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *s) ++viaLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) + { + VIAPtr pVia = VIAPTR(pScrn); + CARD32 temp; +@@ -439,7 +473,7 @@ + if (pVia->CursorARGBSupported) { + #define ARGB_PER_CHUNK (8 * sizeof (chunk) / 2) + for (i = 0; i < (pVia->CursorMaxWidth * pVia->CursorMaxHeight / ARGB_PER_CHUNK); i++) { +- chunk = *s++; ++ chunk = *src++; + for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2) + *dst++ = mono_cursor_color[chunk & 3]; + } +@@ -447,7 +481,7 @@ + pVia->CursorFG = mono_cursor_color[3]; + pVia->CursorBG = mono_cursor_color[2]; + } else { +- memcpy(dst, (CARD8*)s, pVia->CursorSize); ++ memcpy(dst, (CARD8*)src, pVia->CursorSize); + } + switch(pVia->Chipset) { + case VIA_CX700: +@@ -455,6 +489,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + temp = VIAGETREG(VIA_REG_HI_CONTROL0); + VIASETREG(VIA_REG_HI_CONTROL0, temp & 0xFFFFFFFE); +@@ -471,11 +506,17 @@ + } + } + ++/* ++ Set the cursor foreground and background colors. In 8bpp, fg and ++ bg are indices into the current colormap unless the ++ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case ++ and in all other bpps the fg and bg are in 8-8-8 RGB format. ++*/ ++ + static void + viaSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) + { + VIAPtr pVia = VIAPTR(pScrn); +- CARD32 control = pVia->CursorRegControl; + CARD32 pixel; + CARD32 temp; + CARD32 *dst; +@@ -487,12 +528,10 @@ + fg |= 0xff000000; + bg |= 0xff000000; + ++ /* Don't recolour the image if we don't have to. */ + if (fg == pVia->CursorFG && bg == pVia->CursorBG) + return; + +- temp = VIAGETREG(control); +- VIASETREG(control, temp & 0xFFFFFFFE); +- + dst = (CARD32*)pVia->cursorMap; + for (i = 0; i < pVia->CursorMaxWidth * pVia->CursorMaxHeight; i++, dst++) + if ((pixel = *dst)) +@@ -507,6 +546,7 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + if (pVia->pBIOSInfo->FirstCRTC->IsActive) { + temp = VIAGETREG(VIA_REG_HI_CONTROL0); + VIASETREG(VIA_REG_HI_CONTROL0, temp & 0xFFFFFFFE); +@@ -517,7 +557,8 @@ + } + break; + default: +- VIASETREG(control, temp); ++ temp = VIAGETREG(VIA_REG_ALPHA_CONTROL); ++ VIASETREG(VIA_REG_ALPHA_CONTROL, temp & 0xFFFFFFFE); + } + } + +Index: src/via_i2c.c +=================================================================== +--- src/via_i2c.c (revision 811) ++++ src/via_i2c.c (working copy) +@@ -365,9 +365,18 @@ + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaI2CInit\n")); + +- pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex); +- pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex); +- pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex); ++ if (!pVia->I2CDevices) { ++ pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex); ++ pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex); ++ pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex); ++ } else { ++ if (pVia->I2CDevices & VIA_I2C_BUS1) ++ pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex); ++ if (pVia->I2CDevices & VIA_I2C_BUS2) ++ pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex); ++ if (pVia->I2CDevices & VIA_I2C_BUS3) ++ pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex); ++ } + + #ifdef HAVE_DEBUG + if (pVia->I2CScan) { +Index: src/via_dri.c +=================================================================== +--- src/via_dri.c (revision 811) ++++ src/via_dri.c (working copy) +@@ -187,7 +187,7 @@ + return FALSE; + + /* +- * Info frome code-snippet on DRI-DEVEL list; Erdi Chen. ++ * Info from code-snippet on DRI-DEVEL list; Erdi Chen. + */ + + switch (pVia->ChipId) { +@@ -267,6 +267,7 @@ + pVIADRI = pDRIInfo->devPrivate; + pVia->agpSize = 0; + ++ + if (drmAgpAcquire(pVia->drmFD) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", + errno); +@@ -431,17 +432,17 @@ + if (pScrn->bitsPerPixel == 16 || pScrn->bitsPerPixel == 32) { + numConfigs = 12; + if (!(pConfigs = (__GLXvisualConfig *) +- xcalloc(sizeof(__GLXvisualConfig), numConfigs))) ++ calloc(sizeof(__GLXvisualConfig), numConfigs))) + return FALSE; + if (!(pVIAConfigs = (VIAConfigPrivPtr) +- xcalloc(sizeof(VIAConfigPrivRec), numConfigs))) { +- xfree(pConfigs); ++ calloc(sizeof(VIAConfigPrivRec), numConfigs))) { ++ free(pConfigs); + return FALSE; + } + if (!(pVIAConfigPtrs = (VIAConfigPrivPtr *) +- xcalloc(sizeof(VIAConfigPrivPtr), numConfigs))) { +- xfree(pConfigs); +- xfree(pVIAConfigs); ++ calloc(sizeof(VIAConfigPrivPtr), numConfigs))) { ++ free(pConfigs); ++ free(pVIAConfigs); + return FALSE; + } + for (i = 0; i < numConfigs; i++) +@@ -593,23 +594,28 @@ + case VIA_P4M900: + case VIA_VX800: + case VIA_VX855: ++ case VIA_VX900: + pDRIInfo->clientDriverName = "swrast"; + break; + default: + pDRIInfo->clientDriverName = VIAClientDriverName; + break; + } +- pDRIInfo->busIdString = xalloc(64); +- sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", ++ if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { ++ pDRIInfo->busIdString = DRICreatePCIBusID(pVia->PciInfo); ++ } else { ++ pDRIInfo->busIdString = malloc(64); ++ sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", + #ifdef XSERVER_LIBPCIACCESS +- ((pVia->PciInfo->domain << 8) | pVia->PciInfo->bus), +- pVia->PciInfo->dev, pVia->PciInfo->func ++ ((pVia->PciInfo->domain << 8) | pVia->PciInfo->bus), ++ pVia->PciInfo->dev, pVia->PciInfo->func + #else +- ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum, +- ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum, +- ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum ++ ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum, ++ ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum, ++ ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum + #endif +- ); ++ ); ++ } + pDRIInfo->ddxDriverMajorVersion = VIA_DRIDDX_VERSION_MAJOR; + pDRIInfo->ddxDriverMinorVersion = VIA_DRIDDX_VERSION_MINOR; + pDRIInfo->ddxDriverPatchVersion = VIA_DRIDDX_VERSION_PATCH; +@@ -646,7 +652,7 @@ + pDRIInfo->SAREASize = SAREA_MAX; + #endif + +- if (!(pVIADRI = (VIADRIPtr) xcalloc(sizeof(VIADRIRec), 1))) { ++ if (!(pVIADRI = (VIADRIPtr) calloc(sizeof(VIADRIRec), 1))) { + DRIDestroyInfoRec(pVia->pDRIInfo); + pVia->pDRIInfo = NULL; + return FALSE; +@@ -665,7 +671,7 @@ + if (!DRIScreenInit(pScreen, pDRIInfo, &pVia->drmFD)) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] DRIScreenInit failed. Disabling DRI.\n"); +- xfree(pDRIInfo->devPrivate); ++ free(pDRIInfo->devPrivate); + pDRIInfo->devPrivate = NULL; + DRIDestroyInfoRec(pVia->pDRIInfo); + pVia->pDRIInfo = NULL; +@@ -748,7 +754,7 @@ + if (pVia->pDRIInfo) { + if ((pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate)) { + VIADRIIrqExit(pScrn, pVIADRI); +- xfree(pVIADRI); ++ free(pVIADRI); + pVia->pDRIInfo->devPrivate = NULL; + } + DRIDestroyInfoRec(pVia->pDRIInfo); +@@ -756,11 +762,11 @@ + } + + if (pVia->pVisualConfigs) { +- xfree(pVia->pVisualConfigs); ++ free(pVia->pVisualConfigs); + pVia->pVisualConfigs = NULL; + } + if (pVia->pVisualConfigsPriv) { +- xfree(pVia->pVisualConfigsPriv); ++ free(pVia->pVisualConfigsPriv); + pVia->pVisualConfigsPriv = NULL; + } + } +Index: src/via.h +=================================================================== +--- src/via.h (revision 811) ++++ src/via.h (working copy) +@@ -34,7 +34,7 @@ + + /* Video Engines */ + #define VIDEO_ENGINE_UNK 0 /* Unknown video engine */ +-#define VIDEO_ENGINE_CLE 1 /* CLE First generaion video engine */ ++#define VIDEO_ENGINE_CLE 1 /* CLE First generation video engine */ + #define VIDEO_ENGINE_CME 2 /* CME Second generation video engine */ + + /* Video status flag */ +@@ -215,6 +215,9 @@ + #define HQV_DST_STRIDE 0x1F4 + #define HQV_SRC_STRIDE 0x1F8 + ++#define HQV_H_SCALE_CONTROL 0x1B0 ++#define HQV_V_SCALE_CONTROL 0x1B4 ++ + #define PRO_HQV1_OFFSET 0x1000 + /* + * Video command definition +@@ -515,7 +518,23 @@ + #define HQV_FIFO_STATUS 0x00001000 + #define HQV_GEN_IRQ 0x00000080 + #define HQV_FIFO_DEPTH_1 0x00010000 ++/* for CME engine */ ++#define HQV_SW_FLIP_QUEUE_ENABLE 0x00100000 + ++/* for hwDiff->dwNewScaleCtl */ ++#define HQV_H_SCALE_ENABLE 0x80000000 ++#define HQV_H_SCALE_UP 0x00000000 ++#define HQV_H_SCALE_DOWN_FOURTH_TO_1 0x10000000 ++#define HQV_H_SCALE_DOWN_FOURTH_TO_EIGHTH 0x20000000 ++#define HQV_H_SCALE_DOWN_UNDER_EIGHTH 0x30000000 ++ ++#define HQV_V_SCALE_ENABLE 0x80000000 ++#define HQV_V_SCALE_UP 0x00000000 ++#define HQV_V_SCALE_DOWN 0x10000000 ++ ++/* HQV Default Vodeo Color 0x3B8 */ ++#define HQV_FIX_COLOR 0x0643212c ++ + /* HQV_FILTER_CONTROL 0x3E4 */ + #define HQV_H_LOWPASS_2TAP 0x00000001 + #define HQV_H_LOWPASS_4TAP 0x00000002 +@@ -575,6 +594,25 @@ + #define HQV_VDEBLOCK_FILTER 0x80000000 + #define HQV_HDEBLOCK_FILTER 0x00008000 + ++/* new added registers for VT3409.For some registers have different meanings ++ * but the same address,we add postfix _409 to distinguish */ ++#define HQV_COLOR_ADJUSTMENT_PRE_CTRL1 0x160 ++#define HQV_COLOR_ADJUSTMENT_PRE_CTRL2 0x164 ++#define HQV_COLOR_ADJUSTMENT_PRE_CTRL3 0x168 ++#define HQV_COLOR_ADJUSTMENT_PRE_CTRL4 0x16C ++#define HQV_SRC_DATA_OFFSET_CTRL1_409 0x170 ++#define HQV_SRC_DATA_OFFSET_CTRL2_409 0x174 ++#define HQV_SRC_DATA_OFFSET_CTRL3_409 0x178 ++#define HQV_SRC_DATA_OFFSET_CTRL4_409 0x17C ++#define HQV_DST_DATA_OFFSET_CTRL1 0x180 ++#define HQV_DST_DATA_OFFSET_CTRL2 0x184 ++#define HQV_DST_DATA_OFFSET_CTRL3 0x188 ++#define HQV_DST_DATA_OFFSET_CTRL4 0x18C ++#define HQV_RESIDUE_PIXEL_FRAME_STARTADDR 0x1BC ++#define HQV_BACKGROUND_DATA_OFFSET 0x1CC ++#define HQV_SUBP_HSCALE_CTRL 0x1E0 ++#define HQV_SUBP_VSCALE_CTRL 0x1E8 ++ + /* Add new HQV Registers for VT3353: */ + #define HQV_SRC_DATA_OFFSET_CONTROL1 0x180 + #define HQV_SRC_DATA_OFFSET_CONTROL2 0x184 +@@ -588,6 +626,7 @@ + #define HQV_COLOR_ADJUSTMENT_CONTROL2 0x1A4 + #define HQV_COLOR_ADJUSTMENT_CONTROL3 0x1A8 + #define HQV_COLOR_ADJUSTMENT_CONTROL5 0x1AC ++#define HQV_DEFAULT_VIDEO_COLOR 0x1B8 + + #define CHROMA_KEY_LOW 0x00FFFFFF + #define CHROMA_KEY_HIGH 0x00FFFFFF +Index: man/openchrome.man +=================================================================== +--- man/openchrome.man (.../tags/release_0_2_904) (revision 921) ++++ man/openchrome.man (.../trunk) (revision 921) +@@ -22,7 +22,7 @@ The + .B openchrome + driver supports the following chipsets: CLE266, KM400/KN400/KM400A/P4M800, + CN400/PM800/PN800/PM880, K8M800, CN700/VM800/P4M800Pro, CX700, P4M890, K8M890, +-P4M900/VN896/CN896, VX800 and VX855. ++P4M900/VN896/CN896, VX800, VX855 and VX900. + The driver includes 2D acceleration and Xv video overlay extensions. + Flat panel, TV, and VGA outputs are supported, depending on the hardware + configuration. +@@ -59,16 +59,18 @@ are supported: + .BI "Option \*qAccelMethod\*q \*q" string \*q + The driver supports "XAA" and "EXA" acceleration methods. The default + method is XAA, since EXA is still experimental. Contrary to XAA, EXA +-implements acceleration for screen uploads and downlads (if DRI is ++implements acceleration for screen uploads and downloads (if DRI is + enabled) and for the Render/Composite extension. + .TP + .BI "Option \*qActiveDevice\*q \*q" string \*q + Specifies the active device combination. Any string containing "CRT", + "LCD", "DFP", "TV" should be possible. "CRT" represents anything that +-is connected to the VGA port, "LCD" and "DFP" are for laptop panels +-(not TFT screens attached to the VGA port), "TV" is self-explanatory. ++is connected to the VGA port, "LCD" is for laptop panels (not TFT screens ++attached to the VGA port), "DFP" is for screens connected to the DVI port, ++"TV" is self-explanatory. + The default is to use what is detected. The driver is currently unable +-to use LCD and TV simultaneously, and will favour the LCD. ++to use LCD and TV simultaneously, and will favour the LCD. The DVI port is ++not properly probed and needs to be enabled with this option. + .TP + .BI "Option \*qAGPMem\*q \*q" integer \*q + Sets the amount of AGP memory that is allocated at X server startup. +@@ -81,7 +83,7 @@ EXA scratch area in AGP space, it will be allocate + no room for DRI textures, they will be allocated from the DRI part of + VRAM (see the option "MaxDRIMem"). The default amount of AGP is + 32768 kB. Note that the AGP aperture set in the BIOS must be able +-to accomodate the amount of AGP memory specified here. Otherwise no ++to accommodate the amount of AGP memory specified here. Otherwise no + AGP memory will be available. It is safe to set a very large AGP + aperture in the BIOS. + .TP +@@ -131,10 +133,10 @@ as possible to the EXA pixmap storage area. + .TP + .BI "Option \*qMigrationHeuristic\*q \*q" string \*q + Sets the heuristic for EXA pixmap migration. This is an EXA core +-option, and on Xorg server versions after 1.1.0 this defaults to +-"smart". The openchrome driver performs best with "greedy", so you ++option, and starting from __xservername__ server version 1.3.0 this defaults to ++"always". The openchrome driver performs best with "greedy", so you + should really add this option to your configuration file. The third +-possibility is "always", which might become more useful in the future. ++possibility is "smart". + .TP + .BI "Option \*qNoAccel\*q \*q" boolean \*q + Disables the use of hardware acceleration. Acceleration is enabled +@@ -159,9 +161,16 @@ Specifies the size (width x height) of the LCD pan + system. The sizes 640x480, 800x600, 1024x768, 1280x1024, and 1400x1050 + are supported. + .TP ++.BI "Option \*qRotationType\*q \*q" string \*q ++Enabled rotation by using RandR. The driver only support unaccelerated ++RandR rotations "SWRandR". Hardware rotations "HWRandR" is currently ++unimplemented. ++.TP + .BI "Option \*qRotate\*q \*q" string \*q + Rotates the display either clockwise ("CW"), counterclockwise ("CCW") and +-upside-down ("UD"). Rotation is only supported unaccelerated. ++upside-down ("UD"). Rotation is only supported unaccelerated. Adding ++option "Rotate", enables RandR rotation feature. The RandR allows ++clients to dynamically change X screens. + .TP + .BI "Option \*qShadowFB\*q \*q" boolean \*q + Enables the use of a shadow frame buffer. This is required when +@@ -234,6 +243,6 @@ overscan). These modes are made available by the + provided in __xconfigfile__ will be ignored. + + .SH "SEE ALSO" +-__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) ++__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__), EXA(__filemansuffix__), Xv(__filemansuffix__) + .SH AUTHORS + Authors include: ... +Index: src/via_dga.c +=================================================================== +--- src/via_dga.c (revision 811) ++++ src/via_dga.c (working copy) +@@ -89,16 +89,16 @@ + otherPitch = secondPitch ? secondPitch : pMode->HDisplay; + + if (pMode->HDisplay != otherPitch) { +- newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec)); ++ newmodes = realloc(modes, (*num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } + else { +- newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec)); ++ newmodes = realloc(modes, (*num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if (!newmodes) { +- xfree(modes); ++ free(modes); + return NULL; + } + +Index: src/via_id.c +=================================================================== +--- src/via_id.c (revision 811) ++++ src/via_id.c (working copy) +@@ -63,6 +63,7 @@ + {"Giga-byte 7VM400(A)M", VIA_KM400, 0x1458, 0xD000, VIA_DEVICE_CRT}, + {"MSI KM4(A)M-V", VIA_KM400, 0x1462, 0x7061, VIA_DEVICE_CRT}, /* aka "DFI KM400-MLV" */ + {"MSI PM8M2-V", VIA_KM400, 0x1462, 0x7071, VIA_DEVICE_CRT}, ++ {"MSI PM8M-V", VIA_KM400, 0x1462, 0x7104, VIA_DEVICE_CRT}, + {"MSI KM4(A)M-L", VIA_KM400, 0x1462, 0x7348, VIA_DEVICE_CRT}, + {"Abit VA-10 (1)", VIA_KM400, 0x147B, 0x140B, VIA_DEVICE_CRT}, + {"Abit VA-10 (2)", VIA_KM400, 0x147B, 0x140C, VIA_DEVICE_CRT}, +@@ -92,6 +93,7 @@ + {"Shuttle FX21", VIA_K8M800, 0x1297, 0x3052, VIA_DEVICE_CRT}, + {"Shuttle FX83", VIA_K8M800, 0x1297, 0xF683, VIA_DEVICE_CRT | VIA_DEVICE_TV}, + {"Sharp Actius AL27", VIA_K8M800, 0x13BD, 0x1044, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, ++ {"Sharp Mebius PC-CS30H", VIA_K8M800, 0x13BD, 0x1047, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Sharp PC-AE30J", VIA_K8M800, 0x13BD, 0x104B, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Giga-byte GA-K8VM800M", VIA_K8M800, 0x1458, 0xD000, VIA_DEVICE_CRT}, + {"MSI K8M Neo-V", VIA_K8M800, 0x1462, 0x0320, VIA_DEVICE_CRT}, +@@ -114,6 +116,7 @@ + {"Packard Bell Easynote B3 800/B3340", VIA_K8M800, 0x1631, 0xC009, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Packard Bell Imedia 2097", VIA_K8M800, 0x1631, 0xD007, VIA_DEVICE_CRT}, + {"Fujitsu-Siemens Amilo K7610", VIA_K8M800, 0x1734, 0x10B3, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, ++ {"Lenovo ThinkCenter E51 8714", VIA_K8M800, 0x17AA, 0x1008, VIA_DEVICE_CRT}, + {"ASRock K8Upgrade-VM800", VIA_K8M800, 0x1849, 0x3108, VIA_DEVICE_CRT}, + {"Axper XP-M8VM800", VIA_K8M800, 0x1940, 0xD000, VIA_DEVICE_CRT}, + +@@ -138,6 +141,7 @@ + {"Haier A60-440256080BD", VIA_VM800, 0x1019, 0x0F79, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"PCChips P23G", VIA_VM800, 0x1019, 0x1623, VIA_DEVICE_CRT}, + {"ECS P4M800PRO-M", VIA_VM800, 0x1019, 0x2122, VIA_DEVICE_CRT}, ++ {"ECS P4M800PRO-M2 (V2.0)", VIA_VM800, 0x1019, 0x2123, VIA_DEVICE_CRT}, + {"ECS C7VCM", VIA_VM800, 0x1019, 0xAA2D, VIA_DEVICE_CRT}, + {"PCChips V21G", VIA_VM800, 0x1019, 0xAA51, VIA_DEVICE_CRT}, + {"Asustek P5VDC-MX", VIA_VM800, 0x1043, 0x3344, VIA_DEVICE_CRT}, +@@ -152,6 +156,7 @@ + {"MSI PM8PM", VIA_VM800, 0x1462, 0x7222, VIA_DEVICE_CRT}, + {"Twinhead M6", VIA_VM800, 0x14FF, 0xA007, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"RoverBook Partner W500", VIA_VM800, 0x1509, 0x4330, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, ++ {"FIC PTM800Pro LF", VIA_VM800, 0x1509, 0x601A, VIA_DEVICE_CRT}, + {"Clevo/RoverBook Voyager V511L", VIA_VM800, 0x1558, 0x0662, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Clevo M5xxS", VIA_VM800, 0x1558, 0x5406, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Biostar P4M80-M4 / P4VMA-M", VIA_VM800, 0x1565, 0x1202, VIA_DEVICE_CRT}, +@@ -170,6 +175,7 @@ + {"Asustek M2V-MX SE", VIA_K8M890, 0x1043, 0x8297, VIA_DEVICE_CRT}, + {"Foxconn K8M890M2MA-RS2H", VIA_K8M890, 0x105B, 0x0C84, VIA_DEVICE_CRT}, + {"Shuttle FX22V1", VIA_K8M890, 0x1297, 0x3080, VIA_DEVICE_CRT}, ++ {"MSI K8M890M2-V", VIA_K8M890, 0x1462, 0x7139, VIA_DEVICE_CRT}, + {"MSI K9VGM-V", VIA_K8M890, 0x1462, 0x7253, VIA_DEVICE_CRT}, + {"Averatec 226x", VIA_K8M890, 0x14FF, 0xA002, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Fujitsu/Siemens Amilo La 1703", VIA_K8M890, 0x1734, 0x10D9, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, +@@ -183,12 +189,14 @@ + {"Mitac 8515", VIA_P4M900, 0x1071, 0x8515, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Medion Notebook MD96483", VIA_P4M900, 0x1071, 0x8615, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Mitac 8624", VIA_P4M900, 0x1071, 0x8624, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, +- {"VIA VT3364 (P4M900)", VIA_P4M900, 0x1106, 0x3371, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, ++ {"VIA VB8001 Mini-ITX Board (P4M900)", VIA_P4M900, 0x1106, 0x3371, VIA_DEVICE_CRT}, + {"Gigabyte GA-VM900M", VIA_P4M900, 0x1458, 0xD000, VIA_DEVICE_CRT}, + {"MSI VR321", VIA_P4M900, 0x1462, 0x3355, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"MSI P4M900M / P4M900M2-F/L", VIA_P4M900, 0x1462, 0x7255, VIA_DEVICE_CRT}, + {"MSI P4M900M3-L", VIA_P4M900, 0x1462, 0x7387, VIA_DEVICE_CRT}, + {"Twinhead H12V", VIA_P4M900, 0x14FF, 0xA00F, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, ++ {"Twinhead K15V", VIA_P4M900, 0x14FF, 0xA012, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, ++ {"Semp Informática Notebook IS 1462", VIA_P4M900, 0x1509, 0x1D41, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Everex NC1501/NC1503", VIA_P4M900, 0x1509, 0x1E30, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Clevo M660SE", VIA_P4M900, 0x1558, 0x0664, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Clevo M660SR", VIA_P4M900, 0x1558, 0x0669, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, +@@ -224,14 +232,23 @@ + + /*** VX800 ***/ + {"VIA Epia M700", VIA_VX800, 0x1106, 0x1122, VIA_DEVICE_CRT}, ++ {"Siragon ML-6200", VIA_VX800, 0x1106, 0x2211, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, ++ {"Guillemot-Hercules ECafe EC900B", VIA_VX800, 0x1106, 0x3349, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"VIA OpenBook", VIA_VX800, 0x1170, 0x0311, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, /* VIA OpenBook eNote VBE8910 */ + {"Samsung NC20", VIA_VX800, 0x144d, 0xc04e, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, ++ {"FIC CE2A1", VIA_VX800, 0x1509, 0x3002, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Quanta DreamBook Light IL1", VIA_VX800, 0x152d, 0x0771, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + {"Lenovo S12", VIA_VX800, 0x17aa, 0x388c, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, + + /*** VX855 ***/ + {"VIA VT8562C", VIA_VX855, 0x1106, 0x5122, VIA_DEVICE_CRT}, ++ {"OLPC XO 1.5", VIA_VX855, 0x152D, 0x0833, VIA_DEVICE_LCD}, + ++ /*** VX900 ***/ ++ {"Foxconn L740", VIA_VX900, 0x105B, 0x0CFD, VIA_DEVICE_LCD | VIA_DEVICE_CRT}, ++ {"HP T5550 Thin Client", VIA_VX900, 0x1106, 0x7122, VIA_DEVICE_CRT}, ++ ++ + /* keep this */ + {NULL, VIA_UNKNOWN, 0x0000, 0x0000, VIA_DEVICE_NONE} + }; +Index: src/via_timing.h +=================================================================== +--- src/via_timing.h (revision 811) ++++ src/via_timing.h (working copy) +@@ -40,7 +40,7 @@ + #define TIMING_CVT_WARN_REFRESH_RATE_NOT_RB 1 << 3 + + /** +- * Geneartes a CVT modeline ++ * Generates a CVT modeline + * mode must not be null, if mode->name is null a new char* will be allocated. + * + */ |